【问题标题】:What is the best way to sort list with custom sorting parameters in Python?在 Python 中使用自定义排序参数对列表进行排序的最佳方法是什么?
【发布时间】:2011-11-03 14:51:26
【问题描述】:

我有一系列如下所示的列表:

li1 = ['a.1', 'b.9', 'c.8', 'd.1', 'e.2']
li2 = ['a.4', 'b.1', 'c.2', 'd.2', 'e.4']

如何重新排列每个列表中的项目,以便第一项是“b.something”?对于上面的例子:

li1 = ['b.9', 'a.1', 'c.8', 'd.1', 'e.2']
li2 = ['b.1', 'a.4', 'c.2', 'd.2', 'e.4']

在第一个项目之后保持顺序并不重要。感谢您的帮助。

【问题讨论】:

  • 我不确定,但您可能会对这个问题感兴趣:stackoverflow.com/questions/2436607/…
  • 只是想知道为什么每个人都使用s.startwith('b'),而不是s[0] == 'b'。有什么性能优势吗?如果不是,我想保存我大脑的长期记忆使用。
  • @yosukesabai:只有一个答案使用s.startwith('b')。其他人使用s.startwith('b.'),就像问题中要求的那样。
  • @IgnacioVazquez-Abrams:对不起,我想说的是s.startwith('b.') vs s[:2] == 'b.'。第一个优于第二个,如果是,在什么意义上?
  • @yosukesabai:嗯,对于单个元素,startswith 不会在空字符串上崩溃。对于多个字符,除了阅读更好之外,我没有看到任何优势(好吧,您可以指定开始/停止和替代方案,但这里不需要)。

标签: python list sorting


【解决方案1】:

Python 的排序是稳定的,所以不管怎样,你都会保持第一项之后的顺序。

li1.sort(key=lambda x: not x.startswith('b.'))

【讨论】:

  • 这非常巧妙,但我想有些人会争辩说“显式优于隐式”意味着您不应该将布尔值视为可比较的值 (False < True),因此会扩展为喜欢0 if x.startswith('b.') else 1。不过,我不是那些人中的一员。 :)
【解决方案2】:

重新排列每个列表中的项目,使第一个项目是“b.something”

在第一个项目之后保持顺序并不重要。

那不是排序。从概念上讲,你只是想把这个元素放在前面。

换句话说,您需要一个由该元素组成的列表,然后是不是该元素的所有内容。在有多个b.somethings 的情况下稍微捏造一下,并注意到只要第一个元素是b.something,我们不关心会发生什么,我们可以改写:每个元素的列表满足条件(“以b. 开头”),后跟每个不满足条件的元素。 (这有时称为分区;参见 C++ 中的 std::partition 示例。)

在 Python 中,这就像用列表推导描述这两个列表组件并将它们粘在一起一样简单:

[x for x in li if x.startswith('b.')] + [x for x in li if not x.startswith('b.')]

...或者您可以假装您正在排序,只是在应用key 后使用一堆实际上只有两个值的元素,然后应用适当的key,如 Ignacio Vasquez-Abrams '答案。

【讨论】:

  • 这是最接近请求的。无论如何,我不知道sort 的速度有多快,因为您必须使用相同的过滤功能阅读列表两次。
  • 哇,这太酷了。出于某种原因,我从未想过将列表理解结合在一起。谢谢。
  • @Joël 读取列表两次只会导致常量因子开销。排序是 O(n lg n),因为 sort 需要能够任意排序,因此必须进行某种基于比较的排序,而每个过滤列表理解通过通常被视为 O(n)。
  • Python sorting 在最坏的情况下是 O(n lg n);在诸如此类的“大部分排序”数据上(由于 Python 的排序是稳定的,导致相同键的元素已经排序),复杂度接近 O(n)。
【解决方案3】:

您可以使用sorted,它接受key 参数,并返回一个列表:

>>> li1 = ['a.1', 'b.2', 'c.8']
>>> def k(s):
...     if s.startswith('b.'):
...         return 1
...     else:
...         return 2
...
>>> sorted(li1, key=k)
['b.2', 'a.1', 'c.8']

k 应返回可以在可迭代项之间进行比较的内容。

注意:sort 就地更改输入并且不返回任何内容,而 sorted 返回排序列表并且不修改您的列表。两者的工作方式相同。

【讨论】:

    猜你喜欢
    • 2013-07-07
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 2011-11-27
    • 1970-01-01
    相关资源
    最近更新 更多