Reputation: 7635
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
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
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