Using collections.defaultdict
:
d=collections.defaultdict(list)
for item in lst:
d[item[1]].append(item)
d[min(key for key in d.keys() if key!=0)]
Out:
[('NORTHLANDER', 3), ('VOLT', 3)]
Test:
#unwind's solution
def f(lst):
return [y for y in lst if y[1] == min([x for x in lst if x[1] > 0],
key = lambda x: x[1])[1]]
def f2(lst):
d=collections.defaultdict(list)
for item in lst:
d[item[1]].append(item)
return d[min(key for key in d.keys() if key!=0)]
%timeit f(lst)
100000 loops, best of 3: 12.1 us per loop
%timeit f2(lst)
100000 loops, best of 3: 5.42 us per loop
So, defaultdict
seems to be more than twice as fast.
edit
@martineau optimization:
def f3(lst):
lstm = min((x for x in lst if x[1]), key = lambda x: x[1])[1]
return [y for y in lst if y[1] == lstm]
%timeit f3(lst)
100000 loops, best of 3: 4.19 us per loop
And another dict
based solution using set.default
is even a bit faster:
def f4(lst):
d={}
for item in lst:
if item[1] != 0:
d.setdefault(item[1],{})[item]=0
return d[min(d.keys())].keys()
%timeit f4(lst)
100000 loops, best of 3: 3.76 us per loop