[Tutor] Would somebody kindly...

Martin A. Brown martin at linux-ip.net
Thu Oct 30 08:05:15 CET 2014


Hi there Clayton,

> values = [ ('a', 1), ('b', 2), ('a', 5), ('c', 7)]
> key = 'a'
> pair=[]      # -- this assignment is unnecessary
> x=[pair for pair in values if key == pair[0]]
> print(x)
>
> I get [('a', 1), ('a', 5)]

I also get that result.  Good.

> So, what does that first pair do? I see and have used the first comprehension.

I'll point out that somebody (Cameron Simpson, specifically) already 
gave you a hint that might have helped, but maybe you missed it as 
you were trying to understand list comprehensions.

Let's play a little game....I'm going to assume that the variables 
values and key are initialized as you have initialized them above.


Game #1:  Recognize that the name of the variable in the list
   comprehension is ephemeral.

   >>> [frobnitz for frobnitz in values if key == frobnitz[0]]
   [('a', 1), ('a', 5)]

Yes, I guess that's obvious now.  So, this is why people often use 
'x' in these situations.

   >>> [x for x in values if key == x[0]]
   [('a', 1), ('a', 5)]

The variable will probably contain the final element of the input 
sequence after the list comprehension terminates.

   >>> [x for x in values if key == x[0]]
   [('a', 1), ('a', 5)]
   >>> x
   ('c', 7)

If the input sequence had no contents, then the variable will be 
undefined.

   >>> del x
   >>> [x for x in []]
   []
   >>> x
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   NameError: name 'x' is not defined

...but, it is safer, I think, always to treat that variable as 
visible in that one line only.

I have never seen this, but can imagine those who are unusually 
organized or fixated on code cleanliness might remove the variable 
inline after using it.  This is a rare invertebrate--I have never 
seen it in the gardens I have explored:

   [x for x in values if key == x[0]]
   del x


Game #2:  Wait, what?  The variable x is ephemeral?  But, I put 
something important into it!

   x = "password to my cousin's turnip ranching high voltage override"
   >>> x
   "password to my cousin's turnip ranching high voltage override"
   >>> [x for x in values if key == x[0]]
   [('a', 1), ('a', 5)]
   >>> x
   ('c', 7)

By using x in the list comprehension, you are assigning to a 
variable which may (or may not) have already existed.  So, if you 
expect the stuff that was in the variable (x, here) to be there when 
you get back from lunch, you'll be sad, because the Python has eaten 
it just like you told it to.


Game #3:  Observe that you can manipulate what gets returned in the 
output expression from the list comprehension.

   >>> [(x[1], x[0]) for x in values if key == x[0]]
   [(1, 'a'), (5, 'a')]

Hey!  We flipped the position of the number and the alphachar in the 
tuple!  That was fun.


Game #4: Drop a function into the output expression.

Not only can you perform simple sleight of hand like manipulating 
tuples, but you can perform function calls.  So multiply the second 
element of each tuple by a random number.

   >>> import random
   >>> [(x[0], x[1], x[1] * random.randint(0,7000)) for x in values if key == x[0]]
   [('a', 1, 2656), ('a', 5, 4510)]


Good luck,

-Martin

-- 
Martin A. Brown
http://linux-ip.net/


More information about the Tutor mailing list