我有一个 Python 中的列表列表:
k = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4]]
我想从中移除重复的元素。如果是一个正常的列表不列表,我可以使用 set。但不幸的是,该列表不是散列的,不能制作一组列表。只有元组。所以我可以将所有的列表转换为元组,然后使用 set 并返回到列表。但这并不快。
怎样才能以最有效的方式做到这一点?
上述清单的结果应该是:
k = [[5, 6, 2], [1, 2], [3], [4]]
我不在乎维护秩序。
注意: 这个问题是相似的,但不完全是我需要的。搜索所以,但没有找到确切的重复。
基准:
import itertools, time
class Timer(object):
def __init__(self, name=None):
self.name = name
def __enter__(self):
self.tstart = time.time()
def __exit__(self, type, value, traceback):
if self.name:
print '[%s]' % self.name,
print 'Elapsed: %s' % (time.time() - self.tstart)
k = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [5, 2], [6], [8], [9]] * 5
N = 100000
print len(k)
with Timer('set'):
for i in xrange(N):
kt = [tuple(i) for i in k]
skt = set(kt)
kk = [list(i) for i in skt]
with Timer('sort'):
for i in xrange(N):
ks = sorted(k)
dedup = [ks[i] for i in xrange(len(ks)) if i == 0 or ks[i] != ks[i-1]]
with Timer('groupby'):
for i in xrange(N):
k = sorted(k)
dedup = list(k for k, _ in itertools.groupby(k))
with Timer('loop in'):
for i in xrange(N):
new_k = []
for elem in k:
if elem not in new_k:
new_k.append(elem)
“循环”(二次方法)最快的所有短名单。对于长列表,它比除 groupby 方法之外的所有方法都要快。这说得通吗?
对于短列表(代码中的那个) ,100000次迭代:
[set] Elapsed: 1.3900001049
[sort] Elapsed: 0.891000032425
[groupby] Elapsed: 0.780999898911
[loop in] Elapsed: 0.578000068665
对于较长的列表(代码中重复5次的那个) :
[set] Elapsed: 3.68700003624
[sort] Elapsed: 3.43799996376
[groupby] Elapsed: 1.03099989891
[loop in] Elapsed: 1.85900020599