Sorting dictionary using operator.itemgetter
几分钟前,有人问了一个关于根据字典键的值排序的问题。
我刚读到几天前的
并不是说我对这些问题的答案有任何问题,我只是想和
所以口述是:
1 2 3 4 5 6 | >>> mydict = { 'a1': ['g',6], 'a2': ['e',2], 'a3': ['h',3], 'a4': ['s',2], 'a5': ['j',9], 'a6': ['y',7] } |
我试过这个:
1 2 3 | >>> l = sorted(mydict.itervalues(), key=operator.itemgetter(1)) >>> l [['e', 2], ['s', 2], ['h', 3], ['g', 6], ['y', 7], ['j', 9]] |
号
这是我想要的。但是,由于我没有完整的字典(
1 | >>> complete = sorted(mydict.iteritems(), key=operator.itemgetter(2)) |
这不管用(如我所料)。
那么,如何使用
1 2 3 4 5 6 7 8 | In [6]: sorted(mydict.iteritems(), key=lambda (k,v): operator.itemgetter(1)(v)) Out[6]: [('a2', ['e', 2]), ('a4', ['s', 2]), ('a3', ['h', 3]), ('a1', ['g', 6]), ('a6', ['y', 7]), ('a5', ['j', 9])] |
。
关键参数始终是一个函数,一次从iterable(
1 | ('a2',['e',2]) |
所以我们需要一个函数,可以把
注意,
1 2 3 4 5 | In [15]: %timeit sorted(mydict.iteritems(), key=lambda (k,v): v[1]) 100000 loops, best of 3: 7.55 us per loop In [16]: %timeit sorted(mydict.iteritems(), key=lambda (k,v): operator.itemgetter(1)(v)) 100000 loops, best of 3: 11.2 us per loop |
。
itemgetter不支持嵌套(尽管attrgetter支持嵌套)
你得像这样把听筒压扁
1 | sorted(([k]+v for k,v in mydict.iteritems()), key=itemgetter(2)) |
。
答案是——你不能。
1 2 | f = operator.itemgetter(i) f(d) == d[i] |
它永远不会像《以东记》1(2)一样回归。如果您真的想以一种纯粹的功能风格来完成这项工作,您可以编写自己的
1 2 | def compose(f, g): return lambda *args: f(g(*args)) |
号
和使用
1 2 | sorted(mydict.iteritems(), key=compose(operator.itemgetter(1), operator.itemgetter(1))) |
请注意,我不建议这样做:)
通常,索引la
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | >>> from timeit import timeit >>> setup = 'import operator; g = operator.itemgetter(1); ' >>> setup += 'd = {i: list(range(i+2)) for i in range(100)}' >>> kwargs = {'setup': setup, 'number': 10000} >>> timeit('sorted(d.items(), key=lambda kv: kv[1][1])', **kwargs) 0.5251589557155967 >>> timeit('sorted(d.items(), key=lambda kv: g(kv[1]))', **kwargs) 0.7175205536186695 >>> timeit('sorted(d.items(), key=lambda kv: g(kv)[1])', **kwargs) 0.7915238151326776 >>> timeit('sorted(d.items(), key=lambda kv: g(g(kv)))', **kwargs) 0.9781978335231543 |