Search code examples
pythonpython-3.xpython-collections

Counter allowing repetitions


I have a Traffic Light Enum defining possible states:

class TrafficLightPhase(Enum):
    RED = "RED"
    YELLOW = "YELLOW"
    GREEN = "GREEN"

I poll a Traffic Light to get current state every second and I put the values in a deque with this function:

def read_phases():
    while running:
        current_phase = get_current_phase_phases()
        last_phases.append(current_phase)
        time.sleep(1)

I want to group sequences of the same state in order to learn traffic light phases timing.

I tried to use Counter class of collections, like this:

counter = collections.Counter(last_phases)

It groups very well different states, but I'm not able to know when next cycle starts. Is there a similar data structure like Counter that allows repetitions? so I can get results like:

Counter({
         'RED': 10,
         'GREEN': 10, 
         'YELLOW': 3,
         'RED': 10,
         'GREEN': 10, 
         'YELLOW': 3,
         'RED': 10,
         'GREEN': 10, 
         'YELLOW': 3
        })

instead of: Counter({ 'RED': 30, 'GREEN': 30, 'YELLOW': 9 })


Solution

  • I would use itertools.groupby for this. It will group contiguous runs of the same element, then you can check the length for each run.

    >>> from itertools import groupby
    >>> last_phases= ['red', 'red', 'yellow', 'red', 'red', 'green']
    >>> [(key, len(list(group))) for key,group in groupby(last_phases)]
    [('red', 2), ('yellow', 1), ('red', 2), ('green', 1)]