ChatGPT解决这个技术问题 Extra ChatGPT

如何按给定索引处的元素对列表/元组的列表/元组进行排序?

我在列表列表或元组列表中有一些数据,如下所示:

data = [[1,2,3], [4,5,6], [7,8,9]]
data = [(1,2,3), (4,5,6), (7,8,9)]

我想按子集中的第二个元素排序。意思是,按 2,5,8 排序,其中 2 来自 (1,2,3)5 来自 (4,5,6)。这样做的常见方法是什么?我应该在我的列表中存储元组或列表吗?

关于“我应该在列表中存储元组还是列表?”,经验法则是使事物尽可能不可变。如果您不需要就地修改子列表,请将它们设为元组。

u
user2314737
sorted_by_second = sorted(data, key=lambda tup: tup[1])

或者:

data.sort(key=lambda tup: tup[1])  # sorts in place

默认排序模式是升序。要按降序排序,请使用选项 reverse=True

sorted_by_second = sorted(data, key=lambda tup: tup[1], reverse=True)

或者:

data.sort(key=lambda tup: tup[1], reverse=True)  # sorts in place

知道如何将它从大到小排序吗?
@billwild:帮助(排序)。反向=真。
@Stephen 使用 itemgetter 更快更简单:key=itemgetter(1) 并在文件开头:from operator import itemgetter
@Cemre 至于第二个例子,这里的 sort 是 Python 的 List 对象的一个方法,它接收一个 lambda 函数作为它的 key 参数。您可以将其命名为 tupt,或任何您喜欢的名称,它仍然可以工作。这里的 tup 指定列表元组的索引,因此 1 表示将按原始列表 (2, 5, 8) 中元组的第二个值执行排序。
我对“使用 itemgetter 更快、更简单”这一未经证实的说法持怀疑态度。虽然我主观上认为直观的 lambda 方法比不直观的 itemgetter 类更简单,但 itemgetter 确实确实appear to be faster。我很好奇这是为什么。我粗略的怀疑是 lambda 会产生将所有局部变量捕获到闭包上下文中的隐藏成本,而 itemgetter 实例不会。 tl;dr: 始终使用 itemgetter,因为速度胜出。
m
manova
from operator import itemgetter
data.sort(key=itemgetter(1))

这应该是公认的答案。另见 Charlieposted timings,展示了 itemgetter 类的排序平均比同等的 {4 快 126% } 功能。
您还可以按多个索引分层排序,例如 data.sort(key=itemgetter(3,1))
e
elm

对于按多个标准排序,例如按元组中的第二个和第三个元素,让

data = [(1,2,3),(1,2,1),(1,1,4)]

因此定义一个 lambda,它返回一个描述优先级的元组,例如

sorted(data, key=lambda tup: (tup[1],tup[2]) )
[(1, 1, 4), (1, 2, 1), (1, 2, 3)]

R
Rick Smith

如果您想将数组从高到低排序,我只想添加到斯蒂芬的答案中,除了上面的评论之外的另一种方法就是将其添加到该行:

reverse = True

结果如下:

data.sort(key=lambda tup: tup[1], reverse=True)

C
Community

Stephen's answer 是我会使用的。为了完整起见,这里是带有列表推导的 DSU(装饰-排序-不装饰)模式:

decorated = [(tup[1], tup) for tup in data]
decorated.sort()
undecorated = [tup for second, tup in decorated]

或者,更简洁:

[b for a,b in sorted((tup[1], tup) for tup in data)]

Python Sorting HowTo 中所述,自 Python 2.4 以来,当关键函数可用时,这已经是不必要的了。


所以这个答案对 Python 2.3 有用吗?在更新的 Python 版本中是否有任何有效用途,您可以详细说明一下?如果没有,那就不用麻烦了……只是路过,看到了这个,老头就开始搅动了。无论如何,欢呼并感谢您回到 Python 的早期阶段。
K
KernelPanic

为了对元组 (<word>, <count>) 的列表进行排序,count 按降序排列,word 按字母顺序排列:

data = [
('betty', 1),
('bought', 1),
('a', 1),
('bit', 1),
('of', 1),
('butter', 2),
('but', 1),
('the', 1),
('was', 1),
('bitter', 1)]

我使用这种方法:

sorted(data, key=lambda tup:(-tup[1], tup[0]))

它给了我结果:

[('butter', 2),
('a', 1),
('betty', 1),
('bit', 1),
('bitter', 1),
('bought', 1),
('but', 1),
('of', 1),
('the', 1),
('was', 1)]

如果 tup[1] 是一个字符串怎么办?
J
Jaroslav Bezděk

没有 lambda:

def sec_elem(s):
    return s[1]

sorted(data, key=sec_elem)

W
Walter

itemgetter()lambda tup: tup[1] 稍快一些,但增幅相对较小(大约 10% 到 25%)。

(IPython 会话)

>>> from operator import itemgetter
>>> from numpy.random import randint
>>> values = randint(0, 9, 30000).reshape((10000,3))
>>> tpls = [tuple(values[i,:]) for i in range(len(values))]

>>> tpls[:5]    # display sample from list
[(1, 0, 0), 
 (8, 5, 5), 
 (5, 4, 0), 
 (5, 7, 7), 
 (4, 2, 1)]

>>> sorted(tpls[:5], key=itemgetter(1))    # example sort
[(1, 0, 0), 
 (4, 2, 1), 
 (5, 4, 0), 
 (8, 5, 5), 
 (5, 7, 7)]

>>> %timeit sorted(tpls, key=itemgetter(1))
100 loops, best of 3: 4.89 ms per loop

>>> %timeit sorted(tpls, key=lambda tup: tup[1])
100 loops, best of 3: 6.39 ms per loop

>>> %timeit sorted(tpls, key=(itemgetter(1,0)))
100 loops, best of 3: 16.1 ms per loop

>>> %timeit sorted(tpls, key=lambda tup: (tup[1], tup[0]))
100 loops, best of 3: 17.1 ms per loop

请在此处查看 itemgetter 排序解决方案以了解多列的不同反向参数,然后您需要连续多个步骤安排排序:stackoverflow.com/questions/14466068/…
R
Rishi

@Stephen 的回答很中肯!这是一个更好的可视化示例,

为准备好的球员一号球迷大喊! =)

>>> gunters = [('2044-04-05', 'parzival'), ('2044-04-07', 'aech'), ('2044-04-06', 'art3mis')]
>>> gunters.sort(key=lambda tup: tup[0])
>>> print gunters
[('2044-04-05', 'parzival'), ('2044-04-06', 'art3mis'), ('2044-04-07', 'aech')]

key 是一个函数,将被调用以转换集合的项目以进行比较。类似于 Java 中的 compareTo 方法。

传递给 key 的参数必须是可调用的。在这里,lambda 的使用创建了一个匿名函数(它是一个可调用函数)。
lambda 的语法是单词 lambda 后跟一个可迭代的名称,然后是一个代码块。

在下面的示例中,我们正在对包含特定事件和演员姓名的信息 abt 时间的元组列表进行排序。

我们按事件发生的时间对这个列表进行排序——这是元组的第 0 个元素。

注意 - s.sort([cmp[, key[, reverse]]]) 对 s 的项目进行就地排序


s
stackOverflow

我在我的代码中使用它:

#To sort the list based on each element's second integer (elem[1])
sorted(d2, key=lambda elem: elem[1])

根据您要对其进行排序的元素,您可以将其放入

(elem[*insert the index of the element you are sorting it by*])

sorted 创建新列表。要进行就地排序,请使用 .sort(key=...)
b
binarysubstrate

对元组进行排序非常简单:

tuple(sorted(t))