Сравнивать список аргументов с самим собой?

Вроде странный вопрос, но. Мне нужно иметь список строк, мне нужно, чтобы убедиться, что каждая строка в этом списке одинакова.

Например:

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

Каков наилучший способ сделать это?

К вашему сведению, я не знаю, сколько строк будет в списке. Также это очень простой вопрос, но я слишком устал, чтобы думать прямо.

11.12.2008 16:14:25
7 ОТВЕТОВ
РЕШЕНИЕ

Используйте list.count, чтобы получить количество элементов в списке, которые соответствуют значению. Если это число не соответствует количеству предметов, вы знаете, что они не являются одинаковыми.

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

Который будет выглядеть как ...

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

... в производственном коде.

5
11.12.2008 16:27:43

Независимо от того, какую функцию вы используете, вы должны выполнить итерацию по всему массиву хотя бы один раз.

Так что просто используйте цикл for и сравните первое значение с каждым последующим значением. Ничто не может быть быстрее, и это будет три строки. Все, что делает это в меньшем количестве строк, вероятно, будет на самом деле более сложным в вычислительном отношении.

1
11.12.2008 16:22:17
На самом деле, вам нужно только перебрать весь массив в двух худших случаях: все элементы идентичны, или отличается только последний элемент. Используйте этот подход, если производительность является проблемой.
Robert Rossney 11.12.2008 22:04:25

попробуйте (если списки не слишком длинные):

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

это позволяет сравнивать список со списком того же размера, который является одним и тем же первым элементом

0
11.12.2008 16:22:51

Попробуйте создать набор из этого списка:

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

Наборы не могут иметь повторяющиеся элементы.

РЕДАКТИРОВАТЬ: предложение С. Лотта чище:

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

Думайте об этом так:

# Equality returns True or False
all_items_are_same = (len(set(my_list)) == 1)
2
12.12.2008 16:22:30
Элегантно, но требует большего выделения, чем просто проверка счета.
Jordan Parmer 11.12.2008 16:30:06
также: «Если ...: вернуть Ложь» - это немного жутко. Как насчет "same = len (set (thing)) == 1"?
S.Lott 11.12.2008 16:30:14
len(set(a)) == 1в 5 раз медленнее, чем a.count(a[0]) == len(a)(для len (a) в 1000..1000000).
jfs 11.12.2008 17:10:42

возможно

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

это самый читаемый способ.

5
11.12.2008 16:54:36
+1 для читабельности. Почему так много людей всегда пытаются оптимизировать свой ответ для скорости выполнения, когда очень маловероятно, что фрагмент кода OP является горячей точкой для всего приложения?
davidavr 11.12.2008 17:17:43

Я думаю, что это должно быть чем-то, что вы делаете с помощью функции приведения ...

>>> 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'

Однако я не уверен, что у этого есть какие-либо преимущества перед превращением его в комплексное решение. Сбой, если вы хотите проверить, является ли каждое значение в массиве False.

0
11.12.2008 17:00:51

FYI. 5000 итераций как совпадающих, так и несоответствующих версий теста для разных размеров входного списка.

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)

Ясные победители и проигравшие. правила подсчета

Вот версия quickExit, которая работает довольно быстро, но не является одной строкой.

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
3
11.12.2008 17:49:23