How Can I Convert This Tuple Of Tuples Into A Count Of Its Elements?
Solution 1:
Use collections.Counter()
to count how many occurrences you have:
from collections importCounterOutput= Counter(t[0] for t in TupleOfTuples).items()
A Counter()
is a dictionary where keys are mapped to counts; by passing in a generator expression it will do the counting for you. Because it is a dictionary subclass, dict.items()
can then be used to produce a list of (key, count)
tuples.
This does produce a list; simply call tuple()
on that if you insist on having a tuple here.
Demo:
>>> from collections import Counter
>>> TupleOfTuples = ( ('Venue1', 'Name1'), ('Venue1', 'Name2'), ('Venue2', 'Name3'), ('Venue3', 'Name4'), ('Venue3', 'Name5'), ('Venue3', 'Name6') )
>>> Counter(t[0] for t in TupleOfTuples).items()
[('Venue1', 2), ('Venue3', 3), ('Venue2', 1)]
Solution 2:
You can accomplish this quickly and easily using zip(*TupleOfTuples)[n]
to get a sequence of all elements to be counted (where n
is the index of the element in each TupleOfTuples
tuple to count; in this case, 0
), then iterating through the result to get a count for each unique element.
Here's what it looks like:
TupleOfElements = zip(*TupleOfTuples)[0]
Output = tuple((e, TupleOfElements.count(e)) for e in set(TupleOfElements))
I'll explain what's going on:
zip(*TupleOfTuples)[0]
takes your input sequence and transposes it. We want the zero'th element from each TupleOfTuples
element, so we take [0]
from the result. We assign that sequence to TupleOfElements
. (If you wanted to count the Name* elements instead, for instance, you would use zip(*TupleOfTuples)[1]
.)
tuple((e, TupleOfElements.count(e)) for e in set(TupleOfElements))
creates the Output
you want by iterating through TupleOfElements
and returning an element-count pair for each unique element: TupleOfElements
contains all TupleOfTuples
elements in the correct quantity, so we can use TupleOfElements.count(uniqueElement)
will tell us how many occurrences of uniqueElement
there are. We don't need or want to recheck any specific element more than once, though, so we iterate through set(TupleOfElements)
, which will contain exactly one of each element present. We assign the result to Output
, and we're done!
Note: This will return
Output
as atuple
. If you want it as alist
, replace thetuple(..)
in the second line with[..]
, keeping the contents the same.On performance: This code seems to run considerably faster than Martijn's very good solution using
collections.Counter
-- around 3.5x faster for the exampleTupleOfTuples
given, and about 1.25x faster in a much larger but much simpler 88,888-element test I made up to satisfy my own curiosity-- I should imagine because it replaces the dictionary-creation step with a tuple and iterator. It may not be quite as elegant, but I'm a bit proud of it all the same.
Post a Comment for "How Can I Convert This Tuple Of Tuples Into A Count Of Its Elements?"