Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove adjacent duplicate elements in a list using list comprehensions? [duplicate]

Tags:

Is there a way to use list comprehensions in python to filter adjacent duplicates from a list?

Here's an example of what I mean:

>>> xs = [1,2,2,3]
>>> print added.reAdj(xs)
[1,2,3]

A search through SE revealed an earlier inquiry asking a similar but slightly different question: whether all duplicates could be removed from a list, but not explicitly asking for solutions involving list comprehensions. The motivation for using list comprehensions specifically follows a recognition of their advantages over traditional for loops. Users suggested the use of the set() function or standard looping as such:

result = []
most_recent_elem = None
for e in xs:
    if e != most_recent_elem:
        result.append(e)
        most_recent_elem = e

The set() suggestion fails to meet the task in that non-adjacent duplicates are removed, while the loop is effective but verbose.

It seems a means for safely referencing the next element in a list comprehension as follows is needed.

[x for x in xs if x != **x.next()**]

Any ideas?

like image 861
David Shaked Avatar asked Jan 25 '16 05:01

David Shaked


People also ask

How do you use a set to remove duplicate elements from a list?

Remove duplicates from list using Set. To remove the duplicates from a list, you can make use of the built-in function set(). The specialty of set() method is that it returns distinct elements.

How do you remove duplicates from list comprehension?

To remove duplicates from a list in Python, iterate through the elements of the list and store the first occurrence of an element in a temporary list while ignoring any other occurrences of that element. The basic approach is implemented in the naive method by: Using a For-loop to traverse the list.


2 Answers

You can use itertools.groupby:

>>> import itertools
>>> [key for key, grp in itertools.groupby([1, 2, 2, 3])]
[1, 2, 3]

itertools.groupby returns an iterator. By iterating it, you will get a key, group pairs. (key will be a item if no key function is specified, otherwise the return value of the key function). group is an iterator which will yields items grouped by applying key function (if not specified, same values will be grouped)

>>> import itertools
>>> it = itertools.groupby([1, 2, 2, 3])
>>> it
<itertools.groupby object at 0x7feec0863048>
>>> for key, grp in it:
...     print(key)
...     print(grp)
... 
1
<itertools._grouper object at 0x7feec0828ac8>
2
<itertools._grouper object at 0x7feec0828b00>
3
<itertools._grouper object at 0x7feec0828ac8>
>>> it = itertools.groupby([1, 2, 2, 3])
>>> for key, grp in it:
...     print(list(grp))
... 
[1]
[2, 2]
[3]

Above solution, I used only key because the question does not care how many items are adjacent.

like image 108
falsetru Avatar answered Sep 28 '22 16:09

falsetru


You could use list comprehension and enumerate with solution suggested by @AChampion:

xs = [1,2,2,2,1,1]
In [115]: [n for i, n in enumerate(xs) if i==0 or n != xs[i-1]]
Out[115]: [1, 2, 1]

That list comprehension return item if it's first or for the following if it's not equal to previous. It'll work due to lazy evaluations of if statement.

like image 34
Anton Protopopov Avatar answered Sep 28 '22 18:09

Anton Protopopov