【问题标题】:Is list comprehension appropriate here?列表理解在这里合适吗?
【发布时间】:2011-08-04 01:01:42
【问题描述】:

仅当当前迭代的元素不在列表中时,我才必须将元素附加到列表中。

>>> l = [1, 2]
>>> for x in (2, 3, 4):
...     if x not in l:
...             l.append(x)
... 
>>> l
[1, 2, 3, 4]

>>> l = [1, 2]
>>> [l.append(i) for i in (2, 3, 4) if i not in l]
[None, None]
>>> l
[1, 2, 3, 4]

列表推导给出的结果是我想要的,只是返回的列表没用。这是列表推导的好用例吗?

迭代是一个很好的解决方案,但我想知道是否有更惯用的方法来做到这一点?

【问题讨论】:

  • 由于某种原因,我无法再次编辑我的问题。我忘了说我关心元素的顺序。
  • 在日常使用中,我必须在建议的解决方案之间进行调解。 Gerrat's 紧凑,TokenMacGuy's 明确且快速,而 tyz's 位于中间,紧凑且快速,但不太直接。感谢您的精彩回答。我检查了 Gerrat 的答案,因为它更接近我的初衷。

标签: python list list-comprehension duplicates


【解决方案1】:

这个算法,不管有没有列表推导,都不是尽可能高效; list.__contains__ 是 O(n),因此将另一个列表的元素添加到它是 O(n2)。另一方面,set.__contains__ 是 O(log n),因此最佳 方法是使用一个集合来检查成员资格,并使用一个列表来保持顺序。这样,您将执行 n 次 O(log n) 操作,总共 O(n log n),对于合理的 n 值(高于比如说,100 个元素)。

>>> l = [1, 2]
>>> seen = set(l)
>>> for x in (2, 3, 4):
...     if x not in seen:
...         seen.add(x)
...         l.append(x)
... 
>>> l
[1, 2, 3, 4]
>>> 

【讨论】:

    【解决方案2】:

    你可以这样做:

    l.extend((i for i in (2,3,4) if i not in l))
    

    如果添加的列表不是唯一的,此解决方案仍然有效。

    【讨论】:

    • 当要追加的数字不唯一时,此代码将得到不同的结果。如:(2,3,4,4)
    • @user772649:如果有这种可能,那么只需将set 包裹在要添加的数字组周围即可解决该问题。
    • 如果位置信息不重要,请使用 set()。 set() 将改变序列的顺序。
    • @user772649:正确......而且奇怪的是,我正要在对另一个答案(已删除)的评论中指出这一点。
    • @user772649 此代码处理附加的非唯一数字。生成器表达式在list.extend 中一次评估一个数字,因此条件是根据l 的最新内容评估的。试试l = [1, 2]; l.extend(i for i in (2, 3, 3) if i not in l)。如果您使用列表推导而不是生成器表达式,您将得到不同的结果。
    【解决方案3】:

    不鼓励仅对副作用使用列表推导。 3行版本没什么问题。

    如果l 变得很长,您可能需要并行维护一个集合以避免在长列表中使用in l

    【讨论】:

      【解决方案4】:

      我可以建议另一种解决方案:

      orig = [1,2]
      ext = [2,3,4]
      orig.extend(filter( lambda x,p=set(orig):not(x in p or p.add(x)),ext ))
      

      它考虑了元素顺序并在元素重复的情况下起作用。

      顺便说一句,复杂度是 O(n*log(n))。

      【讨论】:

      • 太聪明了,反正+1。
      猜你喜欢
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-17
      • 2016-09-04
      • 2014-12-21
      • 1970-01-01
      • 2017-08-22
      相关资源
      最近更新 更多