python比较元组列表中项目的有效方法



如果元组列表中的一个项在Python中的所有元组中都相同,那么有没有一种有效的方法可以不用循环进行比较?

lst_tups = [('Hello', 1, 'Name:'), ('Goodbye', 1, 'Surname:'), ('See you!', 1, 'Time:')]

预期的输出是返回元组的索引1中项目的所有唯一值

unique = list()
for i in lst_tups:
    item = i[1]
    unique.append(item)

set(unique)
    
Expected Output: 
>>
Unique values: [1]
True if all are equal, otherwise False

我认为集合理解是一种可以接受的方式:

>>> unique = {i[1] for i in lst_tups}
>>> unique
{1}

如果你无论如何都想避免for循环,你可以使用operator.itemgettermap(对于大列表,它会比集合理解稍微高效一些,但可读性更差(:

>>> from operator import itemgetter
>>> unique = set(map(itemgetter(1), lst_tups))
>>> unique
{1}

然后你可以通过判断集合的长度是否为1:来确认元素是否都相同

>>> len(unique) == 1
True

如果你只想得到结果,或者你想比较的项目是不可更改的(比如dict(,你可以使用itertools.pairwise(在Python3.10+中(来比较相邻的元素来判断(但这并不意味着它会更快(:

>>> from itertools import pairwise, starmap
>>> from operator import itemgetter, eq
>>> all(i[1] == j[1] for i, j in pairwise(lst_tups))
True
>>> all(starmap(eq, pairwise(map(itemgetter(1), lst_tups))))
True

根据评论区提出的问题,当你的唯一项目在序列中的另一个位置或元素本身时,上述方法只需要稍作修改即可达到目的,因此这里有两个更通用的解决方案:

def all_equal_by_set(iterable):
    return len(set(iterable)) == 1

def all_equal_by_compare(iterable):
    return all(starmap(eq, pairwise(iterable)))

然后你只需要这样称呼他们:

>>> all_equal_by_set(map(itemgetter(1), lst_tups))
True
>>> all_equal_by_set(tup[1] for tup in lst_tups)   # Note that here is a generator expression, which is no longer comprehension.
True
>>> all_equal_by_compare(map(itemgetter(1), lst_tups))
True
>>> all_equal_by_compare(tup[1] for tup in lst_tups)
True

不使用for循环的解决方案。

import operator
lst_tups = [('Hello', 1, 'Name:'), ('Goodbye', 1, 'Surname:'), ('See you!', 1, 'Time:')]
unique = set(map(operator.itemgetter(1),lst_tups))
print(unique)  # {1}

请考虑以上代码,并根据您的标准编写是否是一种有效的方式

您可以使用chain.from_iterable和带有三个步骤的切片:[1::3]

from itertools import chain
res = list(chain.from_iterable(lst_tups))[1::3]
print(set(res))
# If you want to print True if all are equal, otherwise False
if len(set(res)) == 1:
    print('True')
else:
    print('False')

{1}

最新更新