use*_*312 19 python sorting dictionary
几分钟前,在SO上根据它们的值对字典键进行排序时,问了一个问题.
我刚刚读operator.itemgetter了几天前的排序方法,并决定尝试一下,但它似乎没有起作用.
并不是我对问题的答案有任何问题,我只是想尝试一下operator.itemgetter.
所以这个词是:
>>> mydict = { 'a1': ['g',6],
'a2': ['e',2],
'a3': ['h',3],
'a4': ['s',2],
'a5': ['j',9],
'a6': ['y',7] }
Run Code Online (Sandbox Code Playgroud)
我试过这个:
>>> l = sorted(mydict.itervalues(), key=operator.itemgetter(1))
>>> l
[['e', 2], ['s', 2], ['h', 3], ['g', 6], ['y', 7], ['j', 9]]
Run Code Online (Sandbox Code Playgroud)
这就像我想要的那样.但是,由于我没有完整的字典(mydict.itervalues()),我试过这个:
>>> complete = sorted(mydict.iteritems(), key=operator.itemgetter(2))
Run Code Online (Sandbox Code Playgroud)
这不起作用(正如我预期的那样).
那么我如何使用嵌套键值对dict进行排序operator.itemgetter和调用itemgetter.
unu*_*tbu 30
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])]
Run Code Online (Sandbox Code Playgroud)
关键参数始终是一次从iterable(mydict.iteritems())中提供一个项目的函数.在这种情况下,一个项目可能是这样的
('a2',['e',2])
Run Code Online (Sandbox Code Playgroud)
所以我们需要一个可以('a2',['e',2])作为输入并返回2 的函数.
lambda (k,v): ...是一个匿名函数,它接受一个参数 - 一个2元组 - 并将其解压缩到k和v.因此,当lambda功能被应用到我们的项目,k会'a2'和v会['e',2].
lambda (k,v): operator.itemgetter(1)(v)应用于我们的项目因此返回
operator.itemgetter(1)(['e',2]),其中"itemgets"第二项['e',2],即2.
请注意,这lambda (k,v): operator.itemgetter(1)(v)不是用Python编写代码的好方法.正如gnibbler指出的那样,每个项目operator.itemgetter(1)都会重新计算.那效率很低.使用的目的是创建一个可以多次应用的功能.您不希望每次都重新创建该功能.更具可读性和更快:operator.itemgetter(1)lambda (k,v): v[1]
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
Run Code Online (Sandbox Code Playgroud)
答案是 - 你做不到. operator.itemgetter(i)返回一个返回i其参数项的callable ,即
f = operator.itemgetter(i)
f(d) == d[i]
Run Code Online (Sandbox Code Playgroud)
它永远不会像simething那样回归d[i][j].如果你真的想以纯粹的功能风格来做这件事,你可以编写自己的compose()函数:
def compose(f, g):
return lambda *args: f(g(*args))
Run Code Online (Sandbox Code Playgroud)
并使用
sorted(mydict.iteritems(), key=compose(operator.itemgetter(1),
operator.itemgetter(1)))
Run Code Online (Sandbox Code Playgroud)
请注意,我不建议这样做:)
itemgetter不支持嵌套(尽管attrgetter确实如此)
你需要像这样压扁字典
sorted(([k]+v for k,v in mydict.iteritems()), key=itemgetter(2))
Run Code Online (Sandbox Code Playgroud)