[Tutor] Extending a list within a list comprehension

2006-04-11 Thread Victor Bouffier
Hi all,

I have solved my problem, but would like to know if what I accomplished
can be done with different data using list comprehensions.

the list I want to sort has the following format:

elements = [
(codigo, [ cant, importe, porc]),
(codigo, [ cant, importe, porc]),
...
]

Actual data is:
In [129]: elements[0:5]
Out[129]:
[('2712', [22.0, 3618.80999, 0.0032389476163069883]),
 ('2713', [19.0, 6551.81004, 0.0058640739309320719]),
 ('2710', [21.0, 2553.57999, 0.0022855336019435113]),
 ('2716', [19.0, 8215.27004, 0.0073529224203034461]),
 ('4305', [4.0, 348.37, 0.00031180199598565978])]


And I want to sort descending on 'importe', which is x[1][1] for x in
elements.

What I did was the following, following the Schwarzian Transform:

temporal = []
temporal = [ [x[1][1], (x[0], description[x[0]],
x[1][0], x[1][1], x[1][2] ) ] for x in elements ]
temporal.sort()
temporal.reverse()  # sort descending
elements = [ x[1] for x in temporal ]

If the second element in each array passed as x is of variable length
(that is, it has a different element count than three, in this case),
the program needs to extend the list instead. Without list
comprehensions, and the added capability to utilize and sized list as a
second element, my code ended up looking like the following:

temporal = []
for x in elements:
lst = [x[0], description[x[0]]]
lst.extend(x[1])
temporal.append([x[1][1], lst])
temporal.sort()
temporal.reverse()  # sort descending
elements = [ x[1] for x in temporal ]

Is there a way to use list comprehensions to append or extend the array
as needed by the second code listing?

Thanks.
Victor


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Extending a list within a list comprehension

2006-04-11 Thread John Fouhy
On 12/04/06, Victor Bouffier [EMAIL PROTECTED] wrote:
 elements = [
 (codigo, [ cant, importe, porc]),
 (codigo, [ cant, importe, porc]),
 ...
 ]

 And I want to sort descending on 'importe', which is x[1][1] for x in
 elements.

In python 2.4, you could achieve this by saying:

elements.sort(key=lambda x: x[1][1])

In earlier versions of python, you can do:

elements.sort(lambda x, y: cmp(x[1][1], y[1][1]))

(but this is less efficient than key= in 2.4)

There's also the decorate-sort-undecorate idiom:

dec = [(x[1][1], x) for x in elements]
dec.sort()
elements = [x[1] for x in dec]

--
John.
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Extending a list within a list comprehension

2006-04-11 Thread Alan Gauld
Hi Victor,

I've gotta say that I much prefer the second version here.

 temporal = []
 temporal = [ [x[1][1], (x[0], description[x[0]],
x[1][0], x[1][1], x[1][2] ) ] for x in elements ]
 temporal.sort()
 temporal.reverse()  # sort descending
 elements = [ x[1] for x in temporal ]
 
 
 temporal = []
 for x in elements:
lst = [x[0], description[x[0]]]
lst.extend(x[1])
temporal.append([x[1][1], lst])
 temporal.sort()
 temporal.reverse()  # sort descending
 elements = [ x[1] for x in temporal ]
 

That looks a lot easier to rtead (and debug) and will I suspect be 
easier to maintain. Copmprehensions are great but unfortunately 
can rapidly become incomprehensible!

 Is there a way to use list comprehensions to append or extend the array
 as needed by the second code listing?

There may be but I wouldn't try.
I might however look at using a simple list or dictionary of objects based 
on a class... It might be easier.

Alan G

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Extending a list within a list comprehension

2006-04-11 Thread Victor Bouffier
On Tue, 2006-04-11 at 23:42 +0100, Alan Gauld wrote:
 Hi Victor,
 
 I've gotta say that I much prefer the second version here.
 
  temporal = []
  temporal = [ [x[1][1], (x[0], description[x[0]],
 x[1][0], x[1][1], x[1][2] ) ] for x in elements ]
  temporal.sort()
  temporal.reverse()  # sort descending
  elements = [ x[1] for x in temporal ]
  
  
  temporal = []
  for x in elements:
 lst = [x[0], description[x[0]]]
 lst.extend(x[1])
 temporal.append([x[1][1], lst])
  temporal.sort()
  temporal.reverse()  # sort descending
  elements = [ x[1] for x in temporal ]
  
 
 That looks a lot easier to rtead (and debug) and will I suspect be 
 easier to maintain. Copmprehensions are great but unfortunately 
 can rapidly become incomprehensible!
 
  Is there a way to use list comprehensions to append or extend the array
  as needed by the second code listing?
 
 There may be but I wouldn't try.
 I might however look at using a simple list or dictionary of objects based 
 on a class... It might be easier.
 
 Alan G
 
 

Hi Alan,

I believe you are right. The most pythonic way is not always the most
perlish way ;-) (no offense intended to Perl-comers, but Perl does
tend to promote nesting of expressions).

It is much easier to read and maintain, which is what I will need to do
eventually.
Thanks for the feedback.

Victor


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Extending a list within a list comprehension

2006-04-11 Thread Kent Johnson
Victor Bouffier wrote:

 If the second element in each array passed as x is of variable length
 (that is, it has a different element count than three, in this case),
 the program needs to extend the list instead. Without list
 comprehensions, and the added capability to utilize and sized list as a
 second element, my code ended up looking like the following:
 
 temporal = []
 for x in elements:
 lst = [x[0], description[x[0]]]
 lst.extend(x[1])
 temporal.append([x[1][1], lst])
 temporal.sort()
 temporal.reverse()  # sort descending
 elements = [ x[1] for x in temporal ]
 
 Is there a way to use list comprehensions to append or extend the array
 as needed by the second code listing?

I think you are looking for
temporal = [ [x[0], description[x[0]]] + x[1] for x in elements ]

but I would make two steps, one for the sort using just
   [ (x[0], x) for x in elements ]

then when you pick the data back out you can format it how you like.

Kent

PS to John: the original solution is using DSU, aka Schwarzian Transform

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Extending a list within a list comprehension

2006-04-11 Thread Victor Bouffier
On Tue, 2006-04-11 at 22:17 -0400, Kent Johnson wrote:
 Victor Bouffier wrote:
 
  If the second element in each array passed as x is of variable length
  (that is, it has a different element count than three, in this case),
  the program needs to extend the list instead. Without list
  comprehensions, and the added capability to utilize and sized list as a
  second element, my code ended up looking like the following:
  
  temporal = []
  for x in elements:
  lst = [x[0], description[x[0]]]
  lst.extend(x[1])
  temporal.append([x[1][1], lst])
  temporal.sort()
  temporal.reverse()  # sort descending
  elements = [ x[1] for x in temporal ]
  
  Is there a way to use list comprehensions to append or extend the array
  as needed by the second code listing?
 
 I think you are looking for
 temporal = [ [x[0], description[x[0]]] + x[1] for x in elements ]
 

Hi Kent,
I try this one and get the following error:

TypeError: list objects are unhashable

I figured it is because of the x[0] element being used as a dict key.
Can you explain further where this error comes from? Are you getting it
too?

 but I would make two steps, one for the sort using just
[ (x[0], x) for x in elements ]
 
You are right. This is cleaner and not a big deal to do in two steps.
However for the issue at hand, it still keeps x as a two element list:

[codigo, [ cant, importe, porc]],

which I would like to have extended:

[codigo, cant, importe, porc]

It is not a big deal. That is why I finally went with the longer version
Alan suggested. Before the sort I get a two element list, the second
element being the list I finally want as output.

 then when you pick the data back out you can format it how you like.
 

Right. After the sort I just get that second element in another list
comprehension

lines = [ x[1] for x in temp ]

Thanks for your help.
Victor

 
 Kent
 
 PS to John: the original solution is using DSU, aka Schwarzian Transform
 
 ___
 Tutor maillist  -  Tutor@python.org
 http://mail.python.org/mailman/listinfo/tutor
 

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor