an ingrate newbie complains

Rich Krauter rmkrauter at yahoo.com
Wed Feb 4 19:39:02 EST 2004


Are some of these examples only working because and y have been
initialized by previous runs?
I tried deleting x and y between list comprehensions and they don't work
anymore. Maybe I'm missing the point.

Rich


On Wed, 2004-02-04 at 19:22, Elaine Jackson wrote:
> Thanks to everyone who responded. Digging into this matter of list
> comprehensions a bit more, I turned up some interesting facts. Consider the
> following example:
> 
> >>> f = lambda x,y: x*y+2*pow(y,2)
> >>> g = lambda x: 3*pow(x,2)
> >>> list = [1,2,3,4,5]
> 
> The kind of expression I have in mind would be equivalent to...
> 
> >>> [f(x,y) for (x,y) in [(x,g(x)) for x in list] if y>19]
> [1539, 4800, 11625]
> 
> ...which is equivalent to...
> 
> >>> [f(x,y) for x in list for y in [g(x)] if y>19]
> [1539, 4800, 11625]
> 
> ...but it's not equivalent to...
> 
> >>> [f(x,y) for y in [g(x)] if y>19 for x in list]
> [11325, 11400, 11475, 11550, 11625]
> 
> ...or to...
> 
> >>> [f(x,y) for y in [g(x)] for x in list if y>19]
> [11325, 11400, 11475, 11550, 11625]
> 
> I imagine a good explanation of this discrepancy can only be gotten by dipping
> into the documentation and finding out what an "iterator" is, and that's
> unfortunate (imho), because it means that list comprehensions fail to
> "intuitively suggest the proper meaning to a human reader who has not yet been
> introduced to the construct" (quote taken from the FAQ).
> 
> del list
> ## Peace
> 
> "Skip Montanaro" <skip at pobox.com> wrote in message
> news:mailman.1212.1075922934.12720.python-list at python.org...
> |
> |     Elaine> 1) I find the following behavior puzzling and disappointing:
> |
> |     >>> X=[(1,1),(2,4),(3,9),(4,16),(5,25)]
> |     >>> Y=dict(X)
> |     >>> Z=list(Y)
> |     >>> Z==X
> |     False
> |     >>> Z==Y.keys()
> |     True
> |
> | That list(Y) returns the keys of X is perhaps unfortunate, but the same
> | behavior allows you to write:
> |
> |     for key in Y:
> |         print (key, y[key])
> |
> | which can be an efficiency gain if Y is large (not having to build a list of
> | all the keys ahead of time).  You'll find this to be true though:
> |
> |     W = Y.items()
> |     W.sort()
> |     W == X
> |
> |     Elaine> 2) How come you can't write...
> |
> |     Elaine> if y = f(x) > 3:
> |     Elaine>     <do a bunch of things with x and y>
> |
> | There is a common class of errors in C code:
> |
> |     if (c = 0) {
> |         ...
> |     }
> |
> | Is that supposed to be an assignment or a test?  Python avoids that problem
> | by not allowing assignments within expressions.
> |
> |     Elaine> That kind of syntax would be especially welcome in list
> |     Elaine> comprehensions:
> |
> |     Elaine> [f(x,y) for x in list if y=g(x)<=0]
> |
> | I think you can recast that as:
> |
> |     [f(x,y) for (x,y) in zip(list, [g(z) for z in list]) if y <= 0]
> |
> | but do you really want to?  (This won't work if list is an iterator.)
> |
> |     Elaine> If g(x) is a fairly complicated expression, and y occurs several
> |     Elaine> times in f(x,y), considerable clarity could be gained.
> |
> | If g(x) is a fairly complicated expression and y occurs several times in
> | f(x,y), perhaps you should be using a for loop instead of a list
> | comprehension:
> |
> |     result = []
> |     for x in list:
> |         y = g(x)
> |         if y <= 0:
> |             result.append(f(x,y))
> |     return result
> |
> | (FYI, you shouldn't use "list" as a variable name.  You're shadowing a
> | builtin, a practice that can lead to confusing error messages, if nothing
> | else.)
> |
> | Skip
> |
> 




More information about the Python-list mailing list