我需要一个函数,它接受一个列表并输出True,如果输入列表中的所有元素使用标准相等运算符计算彼此相等,否则输出False。

我觉得最好是遍历列表,比较相邻的元素,然后与所有结果布尔值。但我不知道最python的方法是什么。


当前回答

出现使用itertools。Groupby(参见itertools食谱):

from itertools import groupby

def all_equal(iterable):
    g = groupby(iterable)
    return next(g, True) and not next(g, False)

或不带groupby:

def all_equal(iterator):
    iterator = iter(iterator)
    try:
        first = next(iterator)
    except StopIteration:
        return True
    return all(first == x for x in iterator)

您可以考虑使用许多其他的一行程序:

Converting the input to a set and checking that it only has one or zero (in case the input is empty) items def all_equal2(iterator): return len(set(iterator)) <= 1 Comparing against the input list without the first item def all_equal3(lst): return lst[:-1] == lst[1:] Counting how many times the first item appears in the list def all_equal_ivo(lst): return not lst or lst.count(lst[0]) == len(lst) Comparing against a list of the first element repeated def all_equal_6502(lst): return not lst or [lst[0]]*len(lst) == lst

但它们也有一些缺点,即:

all_equal and all_equal2 can use any iterators, but the others must take a sequence input, typically concrete containers like a list or tuple. all_equal and all_equal3 stop as soon as a difference is found (what is called "short circuit"), whereas all the alternatives require iterating over the entire list, even if you can tell that the answer is False just by looking at the first two elements. In all_equal2 the content must be hashable. A list of lists will raise a TypeError for example. all_equal2 (in the worst case) and all_equal_6502 create a copy of the list, meaning you need to use double the memory.

在Python 3.9中,使用perfplot,我们得到这些计时(越低的Runtime [s]越好):

其他回答

我怀疑这是“最python化的”,但类似于:

>>> falseList = [1,2,3,4]
>>> trueList = [1, 1, 1]
>>> 
>>> def testList(list):
...   for item in list[1:]:
...     if item != list[0]:
...       return False
...   return True
... 
>>> testList(falseList)
False
>>> testList(trueList)
True

会成功的。

如果你对一些更有可读性的东西感兴趣(但当然不是那么高效),你可以尝试:

def compare_lists(list1, list2):
    if len(list1) != len(list2): # Weed out unequal length lists.
        return False
    for item in list1:
        if item not in list2:
            return False
    return True

a_list_1 = ['apple', 'orange', 'grape', 'pear']
a_list_2 = ['pear', 'orange', 'grape', 'apple']

b_list_1 = ['apple', 'orange', 'grape', 'pear']
b_list_2 = ['apple', 'orange', 'banana', 'pear']

c_list_1 = ['apple', 'orange', 'grape']
c_list_2 = ['grape', 'orange']

print compare_lists(a_list_1, a_list_2) # Returns True
print compare_lists(b_list_1, b_list_2) # Returns False
print compare_lists(c_list_1, c_list_2) # Returns False

这是一段具有良好的Python性的代码,并且平衡了简单性和明显性,我认为,这应该也适用于相当老的Python版本。

def all_eq(lst):
    for idx, itm in enumerate(lst):
        if not idx:   # == 0
            prev = itm
        if itm != prev:
            return False
        prev = itm
    return True

我最后写了这样一句话

from itertools import starmap, pairwise
all(starmap(eq, (pairwise(x)))

你可以:

reduce(and_, (x==yourList[0] for x in yourList), True)

python让你导入operator.and_这样的操作符是相当烦人的。从python3开始,还需要导入functools.reduce。

(您不应该使用此方法,因为如果它发现不相等的值,它不会中断,而是会继续检查整个列表。这里只是作为完整性的回答。)