我有一个像这样的 python 2D 列表-
[[3,4],[1,2],[2,1],[6,5]]
我喜欢按行和列两个方向对其进行排序。所以,我想要的输出是这样的-
[[1, 2], [1, 2], [3, 4], [5, 6]]
我所做的是-
list.sort(key = lambda x: (x[1], x[0]))
我得到的是 -
[[2, 1], [1, 2], [3, 4], [6, 5]]
最佳答案
key
参数(和 lambda
)并不意味着修改 list
的内容。相反,它旨在根据应用 key
函数时每个元素的计算方式进行排序。
但是,您可以通过在 key
的函数上调用 .sort()
来使用 key
的副作用来实现您想要的效果争论。由于 .sort()
结果只是 None
,因此您还需要提供用于实际排序的语句本身:
l = [[3,4],[1,2],[2,1],[6,5]]
l.sort(key=lambda x: (x.sort(), x))
print(l)
# [[1, 2], [1, 2], [3, 4], [5, 6]]
但这并不被认为是良好的编程实践。
更干净、更高效,但显然不是单行,方法是:
l = [[3,4],[1,2],[2,1],[6,5]]
for x in l:
x.sort()
l.sort()
print(l)
# [[1, 2], [1, 2], [3, 4], [5, 6]]
基于 key
的方法效率也明显较低,因为它尝试在每个 key
调用时对内部列表进行排序,我们应该期望发生 n log n
次,而严格要求是 n
次,因此某些内部列表不可避免地会被排序超过必要的次数。相反,循环遍历外部列表对每个内部列表显式排序一次。
只是给出一些时间安排的想法:
import random
import copy
import collections
def double_sort_loop(seq):
for x in seq:
x.sort()
seq.sort()
def double_sort_deque(seq):
collections.deque(map(lambda x: x.sort(), seq), maxlen=0)
seq.sort()
def double_sort_key(seq):
seq.sort(key=lambda x: (x.sort(), x))
def gen_input(n, m, v_min=None, v_max=None):
if v_min is None:
v_min = 0
if v_max is None:
v_max = v_min + (2 * m * n)
return [[random.randint(v_min, v_max) for _ in range(m)] for _ in range(n)]
random.seed(0)
base = gen_input(100000, 10)
%timeit seq = copy.deepcopy(base); double_sort_loop(seq)
# 1 loop, best of 3: 1.03 s per loop
%timeit seq = copy.deepcopy(base); double_sort_deque(seq)
# 1 loop, best of 3: 1.02 s per loop
%timeit seq = copy.deepcopy(base); double_sort_key(seq)
# 1 loop, best of 3: 1.19 s per loop
关于python - Python 中使用 lambda 表达式(1 行)自定义 2D 列表排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62965816/