【问题标题】:Python list sorting dependant on if items are in another listPython列表排序取决于项目是否在另一个列表中
【发布时间】:2013-05-16 11:18:13
【问题描述】:

假设我有一个清单:

A = [1,2,3,4,5,6,7,8,9,0]

还有第二个列表:

B = [3,6,9]

对列表 A 进行排序的最佳方法是什么,以便与列表 B 中的项目匹配的任何内容都将出现在开头,结果将是:

[3,6,9,1,2,4,5,7,8,0]

【问题讨论】:

  • B一定是排序的吗?
  • 不,A和B可以以任何顺序开始。它们不一定需要在最后排序,只要 B 中的在 A 中即可。
  • @Ashy 你是什么意思他们没有必要需要排序,你希望他们最后排序吗?
  • 不管是按原始顺序还是按顺序排列,只要出现在B中的在前,同样没有特定顺序。

标签: python list sorting


【解决方案1】:
>>> A = [1,2,3,4,5,6,7,8,9,0]
>>> B = [3,6,9]
>>> sorted(A,key=lambda e: e not in B)
[3, 6, 9, 1, 2, 4, 5, 7, 8, 0]

这是如何工作的:

sorted 根据每个元素的key(element) 的结果对interable 进行排序(key 的默认值是None,这导致它直接根据元素进行排序)。

在我们的例子中,如果e 不是B中,则lambda lambda e: e not in B将返回True,或者如果@987654331,则返回False @B。带有False 的元素被排在前面,最终得到结果。如下所示:

>>> sorted([True,False,False])
[False, False, True]

【讨论】:

  • 更新问题:A 可以是任何顺序,所以目前这不起作用
  • @jamylak:但 OP 也表示确切的输出顺序并不重要,并且 OP 给出的示例——[3,6,9,1,2,4,5,7,8,0]——保留了原始顺序而不是排序。所以我认为这个解决方案有效(尽管如果尺寸更大,将 B 变成一个集合可能是有意义的)。
  • 不错,但更喜欢e not in B 而不是等效的not e in B
  • @wim 你是对的,这更像是 Pythonic!有时我会忘记这些细节。
【解决方案2】:

其中许多答案都明确使用了集合逻辑。但是 Python 内置了它。如果如您所说,只要 B 部分在前,顺序无关紧要,这将处理其余部分:

B = set(B)
list(B.intersection(A)) + list(set(A) - B)

这假设(如您的示例中)没有重复值。如果有,请使用列表理解答案之一。

【讨论】:

  • +1 但我会这样做 >>> A, B = set(A), set(B) >>> list(A & B) + list(A - B) 这也应该更快,因为 B 不需要像在这种情况下那样两次隐式转换为 setA 也被转换为 set 两次
  • @jamylak 他可能想把整个事情重新分配给A[:],所以我接受了你的建议,但跳过了setting 的永久A
【解决方案3】:
>>> A = [1,2,3,4,5,6,7,8,9,0]
>>> B = [3,6,9]
>>> [i for i in B if i in A] + [i for i in A if i not in B]
[3, 6, 9, 1, 2, 4, 5, 7, 8, 0]

【讨论】:

    【解决方案4】:
    >>> A = [1,2,3,4,5,6,7,8,9,0]
    >>> B = [3,6,9]
    >>> b = set(B)
    >>> sorted(A, key=b.__contains__, reverse=True)
    [3, 6, 9, 1, 2, 4, 5, 7, 8, 0]
    

    【讨论】:

      【解决方案5】:

      注意:这将删除重复值 - 但在给定唯一键的情况下有效。

      如果两者都已排序(或按您的意愿排序),那么您可以使用:

      A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
      B = [3, 6, 9]
      
      from collections import OrderedDict
      from itertools import chain
      
      print list(OrderedDict.fromkeys(chain(B, A)))
      # [3, 6, 9, 1, 2, 4, 5, 7, 8, 0]
      

      否则,只需将sorted 应用于AB 或两者兼而有之...

      【讨论】:

      • 如果B 中的项目不在A 中怎么办?我认为我们不应该将其添加到列表中
      猜你喜欢
      • 2013-12-12
      • 2018-01-01
      • 1970-01-01
      • 2019-02-16
      • 2011-03-29
      • 1970-01-01
      • 2013-12-29
      • 2022-12-22
      • 2022-08-24
      相关资源
      最近更新 更多