如何在Python中对压缩列表进行排序?

49
什么是Pythonic方式对压缩过的列表排序?
代码:
names = list('datx')
vals  = reversed(list(xrange(len(names))))
zipped = zip(names, vals)

print zipped

以上代码输出结果为[('d', 3), ('a', 2), ('t', 1), ('x', 0)]

我想要按值排序zipped。理想情况下,它应该看起来像这样[('x', 0), ('t', 1), ('a', 2), ('d', 3)]


前两个答案展示了我对Python的一个小抱怨:存在sortedsort两个函数。 - JasonFruit
4
两者都有其优点:.sort()会原地对列表进行排序,而sorted可以用于任何可迭代对象,但需要使用额外的存储空间来完成任务。 - Ned Batchelder
@JasonFruit:如果你不知道它们的区别,我强烈建议你找出来。 - Matt Joiner
@Matt Joiner, Ned Batchelder:我知道它们的区别;我认为我没有表达清楚。让我感到困扰的是sort()是一个方法,而sorted是一个内置函数。这似乎不太一致。 - JasonFruit
1
@JasonFruit(我知道这是一段时间以前的事了),但sorted与其他特殊的Python语法一致,包括inlenreversed,它们依赖于__contains____len____getitem__ + __len__,分别(我认为sorted需要__getitem____len__,但我不确定)。在许多方面,它也类似于基于__setitem____getitem__[]语法,或者初始化__call__()语法。它们是内置函数,将特殊的内部函数转换为清晰的外部语法。 - Jeff Tratner
@JeffTratner,在那个情境下更有意义。谢谢! - JasonFruit
6个回答

80

非常简单:

sorted(zipped, key=lambda x: x[1])

7
这是Python 3的解决方案。 - VectorVictor

47
sorted(zipped, key = lambda t: t[1])

10
import operator
sorted(zipped, key=operator.itemgetter(1))

如果你想让它更快一点,可以使用ig = operator.itemgetter(1),并将ig作为键函数。


5

在您的情况下,您根本不需要排序,因为您只想要一个列举的反向列表names:

>>> list(enumerate(names[::-1]))      # reverse by slicing
[(0, 'x'), (1, 't'), (2, 'a'), (3, 'd')]

>>> list(enumerate(reversed(names)))  # but reversed is also possible
[(0, 'x'), (1, 't'), (2, 'a'), (3, 'd')]

但是如果你需要对它进行排序,那么你应该使用sorted(由@utdemir或@Ulrich Dangel提供),因为它可以在Python2(zipitertools.zip)和Python3(zip)上工作,并且不会像.sort(...)一样失败并出现AttributeError(因为它只能在Python2 zip上运行,因为那里的zip返回一个list):

>>> # Fails with Python 3's zip:
>>> zipped = zip(names, vals)
>>> zipped.sort(lambda x: x[1])
AttributeError: 'zip' object has no attribute 'sort'

>>> # Fails with Python 2's itertools izip:
>>> from itertools import izip
>>> zipped = izip(names, vals)
>>> zipped.sort(lambda x: x[1])
AttributeError: 'itertools.izip' object has no attribute 'sort'

但是sorted在每种情况下都有效:

>>> zipped = izip(names, vals)
>>> sorted(zipped, key=lambda x: x[1])
[('x', 0), ('t', 1), ('a', 2), ('d', 3)]

>>> zipped = zip(names, vals)  # python 3
>>> sorted(zipped, key=lambda x: x[1])
[('x', 0), ('t', 1), ('a', 2), ('d', 3)]

4

如果可能的话,在第一次排序时将它们压缩会更简单、更有效率。以您的示例为例,这很容易:

>>> names = 'datx'
>>> zip(reversed(names), xrange(len(names)))
<<< [('x', 0), ('t', 1), ('a', 2), ('d', 3)]

0

在分类器中按重要性排序特征(dtc=决策树):

for name, importance in sorted(zip(X_train.columns, 
                dtc.feature_importances_),key=lambda x: x[1]):
    print(name, importance)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接