简体   繁体   English

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

[英]python efficient way to compare item in list of tuples

Is there an efficient way without for loops to compare if an item inside a list of tuples is the same across all tuples in Python?是否有一种没有 for 循环的有效方法来比较元组列表中的项目是否在 Python 中的所有元组中都相同?

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

The expected output is Return all unique values for item in index 1 of the tuple预期的输出是返回元组索引 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

I think the set comprehension is an acceptable way:我认为集合理解是一种可以接受的方式:

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

If you want to avoid the for loop anyway, you can use operator.itemgetter and map (for large lists, it will be slightly more efficient than set comprehension, but the readability is worse):如果你想避免 for 循环,你可以使用operator.itemgettermap (对于大型列表,它会比集合理解稍微高效,但可读性更差):

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

Then you can confirm whether the elements are all the same by judging whether the length of the set is 1:那么就可以通过判断集合的长度是否为1来确认元素是否都一样:

>>> len(unique) == 1
True

If you only want to get the result or the item you want to compare is unhashable (such as dict), you can use itertools.pairwise (in Python3.10+) to compare adjacent elements to judge (but that doesn't mean it will be faster):如果只想得到结果或者要比较的item是unhashable(比如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

According to the questions raised in the comment area, when your unique item is in another position or the element itself in the sequence, the above method only needs to be slightly modified to achieve the purpose, so here are two more general solutions:根据评论区提出的问题,当你的唯一项在另一个位置或者序列中的元素本身时,上面的方法只需要稍作修改即可达到目的,所以这里有两个更通用的解决方案:

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


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

Then you just need to call them like this:然后你只需要这样称呼他们:

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

You can use chain.from_iterable and slicing with three step : [1::3] .您可以使用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}

Solution without using for loop.不使用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}

Please consider above code and write if is an efficient way according to your standards.请考虑上面的代码并根据您的标准编写是否是一种有效的方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM