【问题标题】:Sorting a list/array odd numbers first, then even numbers in Python首先排序列表/数组奇数,然后是Python中的偶数
【发布时间】: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
如何使用functionlambda 或任何其他方式解决此问题?

#已编辑
仅使用lambda

【问题讨论】:

  • 请告诉我们你到目前为止所做的尝试

标签: python list sorting


【解决方案1】:

您有效地对两个键进行排序:主键是 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) :)
  • 使用位运算符的简洁解决方案
【解决方案2】:

我们获取列表,只过滤奇数,排序,然后对值进行排序,然后对偶数执行完全相同的操作。

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 表达式。
【解决方案3】:

这应该可行:

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)

【讨论】:

    【解决方案4】:

    这是一种方法(如果列表中没有重复的数字):

    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
    • 哦,我不知道,我的错。
    • 那么切片部分到底发生了什么?
    • @PSR 我将整个列表排序一次,然后通过对该排序列表进行切片创建一个新列表,首先我选择奇数,因为它们已排序,因此是索引 0 中的所有其他数字,然后是偶数,同样的概念,这次偶数从索引 1 开始,然后我按顺序将它们解包到一个列表中
    【解决方案5】:

    使用元组作为排序键是处理此问题的常用方法:

    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]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-06
      • 2017-05-11
      相关资源
      最近更新 更多