5

我有一个交通灯枚举定义可能的状态:

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

我每秒轮询一个红绿灯以获取当前状态,然后deque使用此函数将值放入 a 中:

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

我想对相同状态的序列进行分组,以学习红绿灯相位计时。

我尝试使用Counterclass of collections,如下所示:

counter = collections.Counter(last_phases)

它对不同的状态进行了很好的分组,但我不知道下一个周期何时开始。是否有类似Counter的允许重复的数据结构?所以我可以得到如下结果:

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

而不是:计数器({'RED':30,'GREEN':30,'YELLOW':9 })

4

2 回答 2

3

我会用itertools.groupby这个。它将对同一元素的连续运行进行分组,然后您可以检查每次运行的长度。

>>> 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)]
于 2018-05-04T14:16:00.530 回答
0

collections.Counter在这里不起作用,因为它不按顺序区分项目。

我建议你使用itertools.groupby.

但是,作为参考,下面是使用collections.defaultdict.

from collections import defaultdict
from itertools import islice, chain, zip_longest

d = defaultdict(lambda: defaultdict(int))

last_phases= ['red', 'red', 'yellow', 'red', 'red', 'green']

c = 0
for i, j in zip_longest(last_phases, islice(last_phases, 1, None)):
    d[c][i] += 1
    if i != j:
        c += 1

res = list(chain.from_iterable(i.items() for i in d.values()))

[('red', 2), ('yellow', 1), ('red', 2), ('green', 1)]
于 2018-05-04T15:16:49.203 回答