Counter.elements
The inverse of counting: turn {element: count} back into a stream of elements. Elements come out grouped in the order they were first inserted, not sorted and not in the original sequence order.
Common call
list(Counter(a=2, b=1).elements())
Returns
['a', 'a', 'b'] — via an iterator
Replaces
[k for k, n in d.items() for _ in range(n)]
Watch out
counts must be ints; a float count raises TypeError
Counter.elements()
→ iterator
Demo
Live evaluation
Count a text, then expand it again: same letters, grouped.
Try:
Inputs
textstrany text
Code
from collections import Counter list(Counter('banana').elements())
Result
['b', 'a', 'a', 'a', 'n', 'n']
"banana" expands to b, a, a, a, n, n: all copies of an element sit together, in the order each element was first counted. elements() uses itertools.repeat under the hood, which is why a count of 1.5 fails with "'float' object cannot be interpreted as an integer".
Common patterns
Rebuild a sorted multiset
sorted() gives a canonical order.
from collections import Counter sorted(Counter(tiles).elements())
Draw from weighted counts
Materialise the population once, then sample from it.
import random from collections import Counter pool = list(Counter(red=3, blue=1).elements()) random.choice(pool)
What is left after removing another multiset
Subtract with -, then expand.
from collections import Counter remaining = list((Counter(hand) - Counter(played)).elements())
Examples
1. Expand counts
from collections import Counter
list(Counter(a=2, b=1).elements())
Returns
['a', 'a', 'b']2. Grouped, not original order
from collections import Counter
''.join(Counter('abab').elements())
Returns
'aabb'3. Zero and negative counts skipped
from collections import Counter
list(Counter(a=0, b=-1, c=2).elements())
Returns
['c', 'c']4. It is an iterator
from collections import Counter
type(Counter('ab').elements()).__name__
Returns
'chain'5. Sorted multiset
from collections import Counter
sorted(Counter('banana').elements())
Returns
['a', 'a', 'a', 'b', 'n', 'n']6. Float counts fail
from collections import Counter
list(Counter(a=1.5).elements())
Returns
TypeError: 'float' object cannot be interpreted as an integerPitfalls
1. Expecting the original sequence back
A Counter only remembers how many, not where. elements() groups equal items.
expects abab
from collections import Counter ''.join(Counter('abab').elements()) == 'abab'
False
compare counts
from collections import Counter Counter(Counter('abab').elements()) == Counter('abab')
True
2. Printing the iterator
elements() returns a lazy itertools.chain object; wrap it in list() to see the items.
len(iterator)
from collections import Counter len(Counter('ab').elements())
TypeError: object of type 'itertools.chain' has no len()
len(list(...))
from collections import Counter len(list(Counter('ab').elements()))
2
When to use
Use it
- Turning counts back into items (for sorting, sampling, joining)
- Checking a multiset result element by element
Reach for something else
- Just the number of items → c.total()
- Huge counts → iterate c.items() instead of materialising millions of copies
Notes
CPython impl
chain.from_iterable(starmap(repeat, self.items())) — itertools.repeat is why non-int counts raise TypeError and non-positive counts yield nothing
Order
Elements are returned in the order first encountered (insertion order), each repeated its count
FAQ
list(counter.elements()) repeats each element count times. list(counter) gives only the distinct elements (the keys).