[Tutor] Ways of removing consequtive duplicates from a list
Peter Otten
__peter__ at web.de
Mon Jul 18 04:25:19 EDT 2022
On 18/07/2022 05:34, dn wrote:
> On 17/07/2022 20.26, Peter Otten wrote:
>> On 17/07/2022 00:01, Alex Kleider wrote:
>>
>>> PS My (at least for me easier to comprehend) solution:
>>>
>>> def rm_duplicates(iterable):
>>> last = ''
>>> for item in iterable:
>>> if item != last:
>>> yield item
>>> last = item
>>
>> The problem with this is the choice of the initial value for 'last':
>
> Remember "unpacking", eg
Try
first, *rest = itertools.count()
;)
If you want the full generality of the iterator-based approach unpacking
is right out.
>> Another fix is to yield the first item unconditionally:
>>
>> def rm_duplicates(iterable):
>> it = iter(iterable)
>> try:
>> last = next(it)
>> except StopIteration:
>> return
>> yield last
>> for item in it:
>> if item != last:
>> yield item
>> last = item
>>
>> If you think that this doesn't look very elegant you may join me in the
>> https://peps.python.org/pep-0479/ haters' club ;)
> This does indeed qualify as 'ugly'. However, it doesn't need to be
> expressed in such an ugly fashion!
On second thought, I'm not exception-shy, and compared to the other options
last = next(it, out_of_band)
if last is out_of_band: return
or
for last in it:
break
else:
return
I prefer the first version. I'd probably go with
[key for key, _value in groupby(items)]
though.
However, if you look at the Python equivalent to groupby()
https://docs.python.org/3/library/itertools.html#itertools.groupby
you'll find that this just means that the "ugly" parts have been written
by someone else. I generally like that strategy -- if you have an "ugly"
piece of code, stick it into a function with a clean interface, add some
tests to ensure it works as advertised, and move on.
More information about the Tutor
mailing list