如果元组列表中的一个项在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.itemgetter
和map
(对于大列表,它会比集合理解稍微高效一些,但可读性更差(:
>>> 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}