简体   繁体   中英

Is list comprehension appropriate here?

I have to append elements to a list only if the current iterated element is not already in the list.

>>> 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]

The list comprehension gives the result is what I want, just the returned list is useless. Is this a good use case for list comprehensions?

The iteration is a good solution, but I'm wondering if there is a more idiomatic way to do this?

This algorithm, either with or without a list comprehension, is not as efficient as possible; list.__contains__ is O(n), and so adding the elements of another list to it is O(n 2 ). On the other hand, set.__contains__ is O(log n), so the best way to do this is to use a set to check for membership, and a list to preserve order. That way you're doing n operations that are O(log n), for a total of O(n log n), which much faster than O(n 2 ) for reasonable values of n (above say, 100 elements).

>>> 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]
>>> 

You could do:

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

This solution still works if the added list is non-unique.

Using list comprehensions just for sideeffects is discouraged. There is nothing wrong with the 3 line version.

If l gets really long, you may want to maintain a set in parallel to avoid using in l on the long list

I can suggest one more solution:

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

It takes into account element order and works in case of element repetition.

BTW, complexity is O(n*log(n)).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM