Python 按第二项(整数值)对元组列表排序

Python 按第二项(整数值)对元组列表排序,python,list,tuples,Python,List,Tuples,我有一个元组列表,看起来像这样: [('abc', 121),('abc', 231),('abc', 148), ('abc',221)] 我想按照元组中的整数值对列表进行升序排序。可能吗 >>> from operator import itemgetter >>> data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)] >>> sorted(data,key=itemg

我有一个元组列表,看起来像这样:

[('abc', 121),('abc', 231),('abc', 148), ('abc',221)]
我想按照元组中的整数值对列表进行升序排序。可能吗

>>> from operator import itemgetter
>>> data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]
>>> sorted(data,key=itemgetter(1))
[('abc', 121), ('abc', 148), ('abc', 221), ('abc', 231)]
在这种情况下,IMO使用
itemgetter
比@cheeken的解决方案更具可读性。它是 由于几乎所有的计算都将在
c
端完成(没有双关语),而不是使用
lambda
,因此速度也更快

>python -m timeit -s "from operator import itemgetter; data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]" "sorted(data,key=itemgetter(1))"
1000000 loops, best of 3: 1.22 usec per loop

>python -m timeit -s "data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]" "sorted(data,key=lambda x: x[1])"
1000000 loops, best of 3: 1.4 usec per loop

尝试将
关键字与
排序()

应该是一个确定如何从数据结构中检索可比较元素的函数。在您的例子中,它是元组的第二个元素,因此我们访问
[1]

有关优化,请参见jamylak使用
itemgetter(1)
的响应,它本质上是python wiki中
lambda x:x[1]

的更快版本:

>>> from operator import itemgetter, attrgetter    
>>> sorted(student_tuples, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]    
>>> sorted(student_objects, key=attrgetter('age'))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

作为python新手,我只想指出,如果数据确实是这样的:

data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]

然后,
sorted()
将根据元组中的第二个元素自动排序,因为第一个元素都是相同的。

添加到Cheeken的答案中, 这是按降序第二项对元组列表排序的方法

sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)],key=lambda x: x[1], reverse=True)

对于lambda避免方法,首先定义自己的函数:

def MyFn(a):
    return a[1]
然后:


对于
Python 2.7+
,这样做会使公认的答案更具可读性:

sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=lambda (k, val): val)

OP中的排序值是整数这一事实与问题本身无关。换句话说,如果排序值是文本,则接受的答案将起作用。我提出这一点也是为了指出排序过程中可以修改排序(例如,考虑大写和小写)


对于就地排序,使用

foo = [(list of tuples)]
foo.sort(key=lambda x:x[0]) #To sort by first element of the tuple


+1我同意
itemgetter()
是一个更好的解决方案。然而,我认为lambda表达式会使
key
的功能更加清晰。+1然而,当我运行您的速度测试时,我注意到“人眼”应该更快。。而且测量速度更快,实际上明显慢了。我对此有点摸不着头脑,然后停止使用python超时模块,只使用linux时间。i、 e.
time`python-c“the code”`
然后我得到了你拼出来的“人眼”结果,以及更快的系统时钟时间。仍然不确定这是为什么,但它是可复制的。我推测这与模块的加载开销有关,但对我来说还不是很重要。@JeffSheffield:注意,jamylak是在设置代码中导入的(在计时之外),而不是在测试代码中导入的。这是完全合理的,因为大多数程序需要不止一次排序,或者需要对更大的集合进行排序,但它们只执行一次导入。(对于那些只需要做一小部分的程序来说……好吧,你说的是不到一微秒的差异,所以谁在乎呢?)@abarnert仅供参考:jamylak正在python-m timeit-s
内部进行导入,但我认为您的观点是,在生产场景中,您只需支付库加载惩罚一次。而且。。。至于谁在乎那微秒。。。你会在意,因为假设你的排序数据会变得相当大,而且一旦数据集增长,微秒会变成真正的秒。@JeffSheffield:这正是问题的关键:导入成本不会随着数据的增长而增长,所以即使它看起来像是你为一个小排序支付的1美元的一大部分,它将是你为一个大排序或一堆小排序支付的500毫秒中一个不相关的部分。这有什么好处?一个好处是有一个定义的函数,你可以在任何地方使用,而不必放置
lambda x:x[1]
在多个代码区域中。另一个好处是,如果它是一个单独的函数,您可以更好地记录/注释。x=[[5,3],1.0345],[5,6],5.098],[5,4],4.89],[5,1],5.97]]有这样的列表,我们可以使用itemgetter()对x[0][1]中的元素进行排序吗?尽管这个答案可能是正确的,最好解释为什么这个答案是正确的,而不是只提供代码。此外,这几乎是一个确切的答案,已经存在,并被接受5年前,所以这并没有真正增加任何网站。看看新的问题,以帮助人们!事实上,这有助于人们寻找合适的方法。虽然这很有帮助,但作为对建议答案的评论可能更合适,表明如何使用与该答案中提供的方法相同的方法来完成相同的任务。Sorted没有进行适当的排序,因此:Sorted_list=Sorted([('abc',121),('abc',231),('abc',148),('abc',221)],key=lambda x:x[1]),reverse=True表示从大到小的顺序。这在Python 3.7中仍然适用。您还可以将多个键添加为元组,如果希望一个键反转,可以添加负号,这将首先使用第一个元素,然后使用第二个元素进行排序:
排序(一些列表,lambda x:(x[0],-x[1])
我只想说这是我有史以来访问量最大的stackoverflow页面;到现在为止,我已经来过500次了。谢谢你,奇肯,如果我能记住这一行代码就好了。注意,原来的列表不会改变。
sorted
函数只会生成一个为您排序的新列表。
sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=lambda (k, val): val)
>>> sorted([(121, 'abc'), (231, 'def'), (148, 'ABC'), (221, 'DEF')], key=lambda x: x[1])
[(148, 'ABC'), (221, 'DEF'), (121, 'abc'), (231, 'def')]
>>> sorted([(121, 'abc'), (231, 'def'), (148, 'ABC'), (221, 'DEF')], key=lambda x: str.lower(x[1]))
[(121, 'abc'), (148, 'ABC'), (231, 'def'), (221, 'DEF')]
foo = [(list of tuples)]
foo.sort(key=lambda x:x[0]) #To sort by first element of the tuple