我有一个定义可能状态的红绿灯枚举:
class TrafficLightPhase(Enum):
RED = "RED"
YELLOW = "YELLOW"
GREEN = "GREEN"
我轮询一个红绿灯以每秒获取当前状态,我将值放在deque
中并使用此功能:
def read_phases():
while running:
current_phase = get_current_phase_phases()
last_phases.append(current_phase)
time.sleep(1)
我想对相同状态的序列进行分组,以便了解交通灯阶段的时间。
我尝试使用Counter
类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, '绿色':30, '黄色':9 })
答案 0 :(得分: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)]
答案 1 :(得分: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)]