Chris Angelico wrote: > Context: Embedded Python interpreter, version 2.6.6 > > I have a list of dictionaries, where each dictionary has a "type" > element which is a string. I want to reduce the list to just the > dictionaries which have the same "type" as the first one. > > lst=[{"type":"calc",...},{"type":"fixed",...},{"type":"calc",...},...] > > I'm seeing a weird difference between two otherwise-equivalent-looking > ways of doing the job. > > type=lst[0]["type"].lower() > > lst=filter(lambda x: x["type"].lower()==type,lst) # Restrict to that one > type > > lst=[i for i in lst if i["type"].lower()==type] # Restrict to that one > type > > If I use the filter() method, the resulting list is completely empty. > If I use the list comprehension, it works perfectly. Oddly, either > version works in the stand-alone interpreter. > > I have no idea where to start looking for the problem. Hints, please! > > Chris Angelico
The assignment writes to the local namespace, the lambda function reads from the global namespace; this will only work as expected if the two namespaces are the same: >>> exec """type = 42; print filter(lambda x: x == type, [42])""" in {}, {} [] >>> ns = {} >>> exec """type = 42; print filter(lambda x: x == type, [42])""" in ns [42] The list comprehension doesn't introduce another namespace, at least in 2.x: $ python2.7 -c 'exec("type = 42; print([x for x in [42] if x == type])", {}, {})' [42] $ python3.2 -c 'exec("type = 42; print([x for x in [42] if x == type])", {}, {})' [] -- http://mail.python.org/mailman/listinfo/python-list