tags:

views:

192

answers:

7

Kind of a weird question, but. I need to have a list of strings i need to make sure that every string in that list is the same.

E.g:

a = ['foo', 'foo', 'boo'] #not valid
b = ['foo', 'foo', 'foo'] #valid

Whats the best way to go about doing that?

FYI, i don't know how many strings are going to be in the list. Also this is a super easy question, but i am just too tired to think straight.

+5  A: 

Use list.count to get the number of items in a list that match a value. If that number doesn't match the number of items, you know they aren't all the same.

if a.count( "foo" ) != len(a)

Which would look like...

if a.count( a[0] ) != len(a)

...in production code.

j0rd4n
Thanks, that's amazing
UberJumper
Shouldn't it be a.count(a[0])?
Rafał Dowgird
+1  A: 

No matter what function you use you have to iterate over the entire array at least once.

So just use a for loop and compare the first value to each subsequent value. Nothing else could be faster, and it'll be three lines. Anything that does it in less lines will probably be more computationally complex actually.

Tom Ritter
You actually only have to iterate over the entire array in the two worst cases: all items are identical, or only the last item is different. Use this approach if performance is an issue.
Robert Rossney
A: 

try (if the lists are not too long):

b == [b[0]] * len(b) #valid
a == [a[0]] * len(a) #not valid

this lets you compare the list to a list of the same size that is all of the same first element

Andrew Cox
+2  A: 

Try creating a set from that list:

if len(set(my_list)) != 1:
    return False

Sets can't have duplicate items.

EDIT: S.Lott's suggestion is cleaner:

all_items_are_same = len(set(my_list)) == 1

Think of it like this:

# Equality returns True or False
all_items_are_same = (len(set(my_list)) == 1)
muhuk
+1 Beat me by seconds!
S.Lott
Elegant but requires more allocation that just checking the count.
j0rd4n
also: "If ...: return False" is kind of creepy. How about "same= len(set(thing)) == 1"?
S.Lott
`len(set(a)) == 1` is 5 times slower than `a.count(a[0]) == len(a)` (for len(a) in 1000..1000000).
J.F. Sebastian
jOrd4n, S.Lott: I agree with you both. Thanks.
muhuk
+5  A: 

Perhaps

all(a[0] == x for x in a)

is the most readable way.

James Hopkin
+1 for readability. Why do so many people always try and optimize their answer for execution speed when it's very unlikely the OP's snippet is the hotspot for the entire app?
davidavr
+1 for `all`! nice stuff (didn't know about it before)
hasen j
A: 

I think that this should be something you do with a reduce function...

>>> a = ['foo', 'foo', 'boo'] #not valid
>>> b = ['foo', 'foo', 'foo'] #valid
>>> reduce(lambda x,y:x==y and x,a)
False
>>> reduce(lambda x,y:x==y and x,b)
'foo'

I'm not sure if this has any advantages over the turning it into a set solution, though. It fails if you want to test if every value in the array is False.

rjmunro
+3  A: 

FYI. 5000 iterations of both matching and unmatching versions of a test on different sizes of the input list.

List Size 10
0.00530 aList.count(aList[0] ) == len(aList)
0.00699 for with return False if no match found.
0.00892 aList == [aList[0]] * len(aList)
0.00974 len(set(aList)) == 1
0.02334 all(aList[0] == x for x in aList)
0.02693 reduce(lambda x,y:x==y and x,aList)

List Size 100
0.01547 aList.count(aList[0] ) == len(aList)
0.01623 aList == [aList[0]] * len(aList)
0.03525 for with return False if no match found.
0.05122 len(set(aList)) == 1
0.08079 all(aList[0] == x for x in aList)
0.22797 reduce(lambda x,y:x==y and x,aList)

List Size 1000
0.09198 aList == [aList[0]] * len(aList)
0.11862 aList.count(aList[0] ) == len(aList)
0.31874 for with return False if no match found.
0.36145 len(set(aList)) == 1
0.65861 all(aList[0] == x for x in aList)
2.24386 reduce(lambda x,y:x==y and x,aList)

Clear winners and losers. count rules.

Here's the quickExit version that runs pretty quickly, but isn't a one-liner.

def quickExit( aList ):
    """for with return False if no match found."""
    value= aList[0]
    for x in aList:
        if x != value: return False
    return True
S.Lott