列表理解是否合适?

时间:2011-08-04 01:01:42

标签: python list list-comprehension duplicates

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

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

VS

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

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

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

4 个答案:

答案 0 :(得分:7)

无论是否有列表推导,此算法都不尽可能高效; list.__contains__是O(n),因此将另一个列表的元素添加到其中是O(n 2 )。另一方面,set.__contains__是O(log n),因此最佳方法是使用集合来检查成员资格,使用列表来保留顺序。这样你就可以进行O(log n)的n次操作,总共为O(n log n),比O(n 2 )快得多,合理的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]
>>> 

答案 1 :(得分:5)

你可以这样做:

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

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

答案 2 :(得分:3)

不建议仅针对副作用使用列表推导。 3行版本没有任何问题。

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

答案 3 :(得分:3)

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

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

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

BTW,复杂度为O(n * log(n))。