如果第一个元素是重复项,则从列表中删除元组的大多数pythonic方法 [英] Most pythonic way to remove tuples from a list if first element is a duplicate
问题描述
到目前为止,我的代码非常丑陋:
The code I have so far is pretty ugly:
orig = [(1,2),(1,3),(2,3),(3,3)]
previous_elem = []
unique_tuples = []
for tuple in orig:
if tuple[0] not in previous_elem:
unique_tuples += [tuple]
previous_elem += [tuple[0]]
assert unique_tuples == [(1,2),(2,3),(3,3)]
必须有一个更加Python化的解决方案.
There must be a more pythonic solution.
推荐答案
如果您不在乎返回的元组是否重复,则可以始终将列表转换为字典并返回:
If you don't care which tuple round you return for duplicates, you could always convert your list to a dictionary and back:
>>> orig = [(1,2),(1,3),(2,3),(3,3)]
>>> list(dict(orig).items())
[(1, 3), (2, 3), (3, 3)]
If you want to return the first tuple round, you could reverse your list twice and use an OrderedDict
, like this:
>>> from collections import OrderedDict
>>> orig = [(1,2),(1,3),(2,3),(3,3)]
>>> new = list(OrderedDict(orig[::-1]).items())[::-1]
[(1, 2), (2, 3), (3, 3)]
这些不是最有效的解决方案(如果非常重要,则 ),但是它们确实构成了惯用的单行代码.
These are not the most efficient solutions (if that's of great importance) , but they do make for nice idiomatic one-liners.
请注意速度的差异,并且如果您不关心返回的元组,则第一种选择的效率会更高:
Note the difference in speed, and that should you not care which tuple round you return, the first option is much more efficient:
>>> import timeit
>>> setup = '''
orig = [(1,2),(1,3),(2,3),(3,3)]
'''
>>> print (min(timeit.Timer('(list(dict(orig).items()))', setup=setup).repeat(7, 1000)))
0.0015771419037069459
相比
>>>setup = '''
orig = [(1,2),(1,3),(2,3),(3,3)]
from collections import OrderedDict
'''
>>> print (min(timeit.Timer('(list(OrderedDict(orig[::-1]).items())[::-1])',
setup=setup).repeat(7, 1000)))
0.024554947372323
根据这些速度测试,第一种选择的速度快将近15倍.
The first option is nearly 15 times faster according to these speed tests.
话虽这么说, Saksham的答案也是O(n)
,并明智地粉碎了这些字典方法:
That being said however, Saksham's answer is also O(n)
and smashes these dictionary methods efficiency wise:
>>> setup = '''
orig = [(1,2),(1,3),(2,3),(3,3)]
newlist = []
seen = set()
def fun():
for (a, b) in orig:
if not a in seen:
newlist.append((a, b))
seen.add(a)
return newlist
'''
>>> print (min(timeit.Timer('fun()', setup=setup).repeat(7, 1000)))
0.0004833390384996095
这篇关于如果第一个元素是重复项,则从列表中删除元组的大多数pythonic方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!