I am working in Python and considering the following problem: given a list, such as [1, 0, -2, 0, 0, 4, 5, 0, 3]
which contains the integer 0 multiple times, I would like to have the indices at of these 0 and for each one, the number of times it appears in the list until a different element appears or the list ends.
Given l = [1, 0, -2, 0, 0, 4, 5, 0]
, the function would return ((1, 1), (3, 2), (7, 1))
. The result is a list of tuples. The first element of the tuple is the index (in the list) of the given element and the second is the number of times it is repeated until a different element appears or the list ends.
Naively, I would write something like this:
def myfun(l, x):
if x not in l:
print("The given element is not in list.")
else:
j = 0
n = len(l)
r = list()
while j <= (n-2):
count = 0
if l[j] == x:
while l[j + count] == x and j <= (n-1):
count +=1
r.append((j, count))
j += count
else:
j += 1
if l[-1] == x:
r.append((n-1, 1))
return r
But I was wondering whether there would be a nicer (shorter?) way of doing the same thing.
What are duplicates in a list? If an integer or string or any items in a list are repeated more than one time, they are duplicates.
Not the prettiest, but a one-liner:
>>> import itertools
>>> l=[1, 0, -2, 0, 0, 4, 5, 0]
>>> [(k[0][0],len(k)) for k in [list(j) for i,j in itertools.groupby(enumerate(l), lambda x: x[1]) if i==0]]
[(1, 1), (3, 2), (7, 1)]
First, itertools.groupby(enumerate(l), lambda x: x[1])
will group by the second item of enumerate(l)
, but keep the index of the item.
Then [list(j) for i,j in itertools.groupby(enumerate(l), lambda x: x[1]) if i==0]
will keep only the 0 values.
Finally, the last list comprehension is needed because list(j)
consume the itertools object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With