Preserve insertion order while counting first appearances
Preserve insertion order while counting first appearances
By Batu. AI assistance was used to prepare this article.
A collections.Counter is a dictionary subclass, so it retains the insertion order of distinct keys on supported modern Python versions. Calling update([event]) increments the count for one event; it does not replace the previous count. Therefore the first call that introduces a value fixes that value’s position, while subsequent appearances only change its number.
from collections import Counter
events = ["open", "save", "open", "close", "save", "open"]
counts = Counter()
for event in events:
counts.update([event])
first_seen_counts = list(counts.items())
assert first_seen_counts == [("open", 3), ("save", 2), ("close", 1)]
assert counts.most_common() == [("open", 3), ("save", 2), ("close", 1)]
print(first_seen_counts)
print(f"unique={list(counts)}")
Expected stdout
[('open', 3), ('save', 2), ('close', 1)]
unique=['open', 'save', 'close']
list(counts.items()) is the important result here: it reports each event with its final count in first-appearance order. most_common() is not a substitute when counts differ, because it sorts primarily by count; it uses first-appearance order only to break equal-count ties. The second assertion happens to match the desired ordering for this small input, but code needing a stable event chronology should use the dictionary order directly.
Counter keys must be hashable, so a list or dictionary event cannot be counted without converting it to a stable hashable representation. Its counts are not restricted to positive integers, either; a mapping passed to update() can add negative values. Finally, Counter.update() treats an iterable as elements, not as (key, value) pairs. Pass a mapping when the input already contains increments.
Source: Python Counter documentation.
Comments
Post a Comment