Skip to content Skip to sidebar Skip to footer

How Can I Convert This Tuple Of Tuples Into A Count Of Its Elements?

I have this tuple of tuples: TupleOfTuples = (('Venue1', 'Name1'), ('Venue1', 'Name2'), ('Venue2', 'Name3'), ('Venue3', 'Name4'), ('Venue3', 'Na

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 a tuple. If you want it as a list, replace the tuple(..) 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 example TupleOfTuples 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?"