我有一个元组列表,并且如果它的第一项与列表中其他元组的第一项匹配,则需要删除元组。第三项可能相同,也可能不同,所以我不能使用set(我已经看到了这个问题-Grab unique tuples in python list, irrespective of order,这与我的问题不同)
例如,如果我得到 a 为:
[(0,13,'order1'),(14,27,'order2'),(14,27,'order2.1'),(0,13, 'order1'),(28、41,'order3')]
我希望输出为:
[((14,27,'order2'),(0,13,'order1'),(28,41,'order3')]
我正在使用以下代码获得所需的输出。
passport
是否有更好或更多的pythonic方法来实现相同目标。
答案 0 :(得分:3)
通常的方法是将dict锁定为您想通过其进行重复数据删除的方式,例如:
>>> a = [(0, 13, 'order1'), (14, 27, 'order2'), (14, 27, 'order2.1'), (0, 13, 'order1'), (28, 41, 'order3')]
>>> print(*{tup[:2]: tup for tup in a}.values())
(0, 13, 'order1') (14, 27, 'order2.1') (28, 41, 'order3')
这是 O(n)时间复杂度,优于基于 O(n log n) groupby的方法。
答案 1 :(得分:1)
您可以在分组的排序列表中获得每个组的第一个元素:
from itertools import groupby
from operator import itemgetter
a = [(0, 13, 'order1'), (14, 27, 'order2'), (14, 27, 'order2.1'), (0, 13, 'order1'), (28, 41, 'order3')]
result = [list(g)[0] for k, g in groupby(sorted(a), key=itemgetter(0))]
print(result)
答案 2 :(得分:1)
在遍历列表时,应避免修改列表。相反,您可以使用流行的itertools
unique_everseen
recipe,也可以在第三方more_itertools
中使用。只需在key
参数中使用operator.itemgetter
:
from more_itertools import unique_everseen
from operator import itemgetter
res = list(unique_everseen(L, key=itemgetter(0, 1)))
此解决方案花费O( n )时间,但通常比基于字典的解决方案效率 少,尽管其意图可以说更清晰。