Below the Radar
Below the Radar

Reputation: 7635

check if the second element of tuples in list of tuples are all the same

I would like to check if the second element of tuples in list of tuples are all the same

features = [(a,b), (c,b), (a,d)]

The first element of the tuple can be different.

x = []
for feature, geom_type in features:
    x.append(geom_type)
y = collections.Counter(x)
print len([i for i in y if y[i]>1])

Upvotes: 0

Views: 3332

Answers (2)

Sylvain Leroux
Sylvain Leroux

Reputation: 52070

For very long lists, it is not efficient to build a complete set as you are able to abort as soon as a "non-match" is encountered. In that case, a plain old imperative loop is to be considered:

def check_if_second_are_same(lst):
    for item in lst:
        if item[1] != lst[0][1]:
            return False
    return True

Upvotes: 1

Martijn Pieters
Martijn Pieters

Reputation: 1125388

You are overcomplicating matters. All you need is a set, then test if the set contains just one element:

len({g for f, g in features}) <= 1

The {expr for targets in iterable} construct is a set comprehension; it builds a set from all the second elements in your tuples. It'll only hold the unique elements; if it's length is not 1 then there were at different values.

If features is very large, you may want to bail out early rather than iterate over all elements; some itertools magic could do that:

from itertools import dropwhile

def unique(it):
    it = iter(it)
    try:
        next(dropwhile(lambda e, f=next(it): e == f, it))
    except StopIteration:
        return True
    else:
        return False

then use as:

if unique(g for f, g in features):

The dropwhile() returns the next element that is not equal to the very first value in the it iterable. If there is no such element, StopIteration is raised and we know the whole iterable contains just the one value. If no StopIteration was raised we found evidence it wasn't unique.

It'll also return True if there are no elements in it at all.

Demo:

>>> features = [('a', 'b'), ('c', 'b'), ('a', 'd')]
>>> len({g for f, g in features}) <= 1
False
>>> unique(g for f, g in features)
False
>>> features = [('a', 'b'), ('c', 'b'), ('a', 'b')]
>>> len({g for f, g in features}) <= 1
True
>>> unique(g for f, g in features)
True

Upvotes: 6

Related Questions