【发布时间】:2022-01-23 17:56:12
【问题描述】:
我想在 Python3 中对列表进行排序,首先是奇数,然后是偶数。
让列表为li = [4, 1, 5, 8, 2, 9, 3, 10, 7, 6]
输出应为:1 3 5 7 9 2 4 6 8 10
如何使用function 或lambda 或任何其他方式解决此问题?
#已编辑
仅使用lambda。
【问题讨论】:
-
请告诉我们你到目前为止所做的尝试
我想在 Python3 中对列表进行排序,首先是奇数,然后是偶数。
让列表为li = [4, 1, 5, 8, 2, 9, 3, 10, 7, 6]
输出应为:1 3 5 7 9 2 4 6 8 10
如何使用function 或lambda 或任何其他方式解决此问题?
#已编辑
仅使用lambda。
【问题讨论】:
您有效地对两个键进行排序:主键是 int 是偶数还是奇数,并且您希望奇数比较“更小”。辅助键就是整数本身。这都可以通过对(主键,辅助键)的元组进行排序来表达,这可以通过传递给排序的可选key=参数的函数直接构建这些元组来表达:
>>> li = [4, 1, 5, 8, 2, 9, 3, 10, 7, 6]
>>> sorted(li, key=lambda i: (1 - (i & 1), i))
[1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
替代方案:在任何情况下,如果您对 N 键进行排序,而不是使用 N-tuple 键进行单一排序,您可以改为对单个键进行 N 排序,最低有效键第一的。这可能并不明显,并且依赖于 Python 的排序算法是“稳定的”(保留比较相等的项目的输入顺序)。具体来说,对于手头的情况,这是一种方法:
>>> sorted(sorted(li), key=lambda i: i % 2, reverse=True)
[1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
出于令人不舒服的原因,这样做可能会更快。尽管您正在做更多的分类,但更便宜的比较可能足以弥补这一点。
【讨论】:
sorted 的人。很高兴再次见到你,顺便说一句。我想上次是eight years ago, to the day in fact.
(-(i % 2), i) :)
我们获取列表,只过滤奇数,排序,然后对值进行排序,然后对偶数执行完全相同的操作。
li = [4, 1, 5, 8, 2, 9, 3, 10, 7, 6]
final_li = [*sorted(filter(lambda x: x % 2, li)), *sorted(filter(lambda x: x % 2 == 0, li))]
【讨论】:
lambda 表达式。
这应该可行:
array = [4, 1, 5, 8, 2, 9, 3, 10, 7, 6]
even = []
odd = []
for value in sorted(array):
if value % 2 == 0:
even.append(value)
else:
odd.append(value)
combined = even + odd
print(*combined)
【讨论】:
这是一种方法(如果列表中没有重复的数字):
li = [4, 1, 5, 8, 2, 9, 3, 10, 7, 6]
sorted_li = sorted(li)
print([*sorted_li[::2] , *sorted_li[1::2]])
输出:
[1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
我对整个列表进行一次排序,然后通过对该排序列表进行切片来创建一个新列表,首先我选择奇数,因为它们已排序,所以从索引 0 开始每隔一个数字,然后是偶数,即同样的概念,这次偶数从索引 1 开始,然后我按顺序将它们解压缩到一个列表中
【讨论】:
slicing,
使用元组作为排序键是处理此问题的常用方法:
li = sorted(li,key=lambda n: (1-n%2,n))
或者,您可以在排序和连接结果之前分离奇数和偶数。如果奇数和偶数之间的差值大致相等,这将运行两个较小的排序而不是一个大排序。
odds = (n for n in li if n%2) # generators, avoid using extra memory
evens = (n for n in li if n%2==0) # you could also use filter()
li = sorted(odds)+sorted(evens)
print(li)
[1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
【讨论】: