python: what is go keyword in generator expression while operating dictionary -
this simple query while checking out various discussions on dictionary comprehension on here. did this:
newlist=[{v:k} k,v in dicnew.items() if v==value] >>> newlist [{2: 'a'}, {2: 'ac'}, {2: 'b'}, {2: 'love'}]
what did next this:
newlist.setdefault(v,[]).append((v,k) k,v in dicnew.items() if v==value) >>> newlist {'go': [<generator object <genexpr> @ 0x01e98d50>]}
what happened? 'go'?
you called .setdefault()
a value of v
:
newlist.setdefault(v,[])
and v
must have been defined , set 'go'
. had run code in new interpreter, or executed del v
first, python have raised nameerror
exception instead:
>>> newlist = {} >>> newlist.setdefault(v,[]).append((v,k) k,v in dicnew.items() if v==value) traceback (most recent call last): file "<stdin>", line 1, in <module> nameerror: name 'v' not defined >>> v = 'go' >>> newlist.setdefault(v, []) [] >>> newlist {'go': []}
the setdefault()
part executed before .append()
method executed. v
name used in generator expression inside .append()
method has nothing v
name used in .setdefault()
call.
in python 2.7 , earlier, list comprehension variables 'leak' parent scope:
>>> [foo foo in range(3)] [0, 1, 2] >>> foo 2
as such, v
set in previous loop, , last value assigned 'go'
.
if wanted 'invert' dictionary collecting list of keys each value, use:
from collections import defaultdict keys_for_value = defaultdict(list) key, value in original_dict.iteritems(): keys_for_value[value].append(key)
if must insist on one-liner, use itertools.groupby
, sorting:
from itertools import groupby operator import itemgetter v = itemgetter(1) keys_for_value = {value: [k k, v in items] value, items in groupby(sorted(original_dict.iteritems(), key=v, key=v)}
this going slower, need sort dictionary items first (cost o(n log n)) before looping on sorted results (itself o(n), total of o(n) + o(n log n)), opposed simple o(n) complexity of using defaultdict
, for
loop.
Comments
Post a Comment