Golanu Delamare
Golanu Delamare

Reputation: 71

How to effciently calculate non-consecutive number of appereances of element in list?

I'm trying to find out how many times a certain element is non-consecutively appearing in a list.

By that I mean:

list = [10,10,10,11,12,10,12,14,10,10,10]
element_searched = 10

=> expected_output = 3

So that means that 10 is appearing 3 times in a the list.

My code so far that seems to be working:

elements = [11, 10, 12]
row = [10,10,10,10,10,10,10,10,10,11,11,11,11,11,10,10,10,10,12,12,12,12,12,11,11,11,11,12,12,12,12,10]

element_on = False
for element in elements:
    sequence = 0
    for i in range(len(row)):
        if element == row[i] and element_on==False:
            sequence += 1
            element_on = True
        elif element==row[i] and element_on==True:
            pass
        elif element != row[i] and element_on==True:
            element_on = False
        elif element != row[i] and element_on == False:
            element_on = False

    print(f"For element {element} the number ob sequences is: {sequence} ")

I am getting the desired output but I am wondering if there is a more elegant and especially a faster way.

Upvotes: 2

Views: 397

Answers (4)

Thomas Panzeri
Thomas Panzeri

Reputation: 21

I would use a simple dictionary:

row = [10,10,10,10,10,10,10,10,10,11,11,11,11,11,10,10,10,10,12,12,12,12,12,11,11,11,11,12,12,12,12,10]

counter = {}
last_item = None
for item in row:
    if last_item != item:
        counter[item] = counter.get(item, 0) + 1
        last_item = item

print (counter)

Upvotes: 1

ipj
ipj

Reputation: 3598

Try this:

row = [10,10,10,10,10,10,10,10,10,11,11,11,11,11,10,10,10,10,12,12,12,12,12,11,11,11,11,12,12,12,12,10]
sr = pd.Series(row, name = "x")
sr[sr.groupby(sr.shift(-1).bfill(0).ne(sr)).transform('cumcount')==1].value_counts()

Output:

10    3
12    2
11    2

First column is x value, second is number of sequences.

More compact and faster way:

from  itertools import groupby    
pd.Series([k for k, g in groupby(row)]).value_counts()

Another solution:

np.unique([k for k, g in groupby(row)], return_counts=True)

Result:

(array([10, 11, 12]), array([3, 2, 2], dtype=int64))

Alternatively use np.bincount:

np.bincount([k for k, g in groupby(row)])

But the output will be slightly different:

array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2], dtype=int64)

Upvotes: 2

Lajos Arpad
Lajos Arpad

Reputation: 76692

A few thoughts which should guide you:

  • you need a variable which will store the previous value
  • a map of elements, the key being the value of the element, the value being the number of occurrences found so far
  • on each iteration check if the current element equals the previous element and if not, then increment the map item having the current element as key
  • set previous to current value at each step

Upvotes: 1

Kenan
Kenan

Reputation: 14104

I think this is what you want. Groupby the list by similiar elements and then sum the counts

import itertools

element_searched = 10

expected_output = sum([i.count(element_searched) for i in itertools.groupby(list)])

3

Upvotes: 1

Related Questions