Pythonのリストのリストがあります。
k = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4]]
そして、そこから重複する要素を削除したいと思います。それが私が使用できるリストではなく、通常のリストであったかどうかsetです。しかし残念なことに、そのリストはハッシュ可能ではなく、リストのセットを作成できません。タプルのみ。したがって、すべてのリストをタプルに変換してから、セットを使用してリストに戻すことができます。しかし、これは速くはありません。
これを最も効率的な方法で行うにはどうすればよいですか?
上記のリストの結果は次のようになります。
k = [[5, 6, 2], [1, 2], [3], [4]]
順序の保存は気にしません。
注:この質問は似ていますが、私が必要としているものとはまったく異なります。SOを検索しましたが、完全な重複は見つかりませんでした。
ベンチマーク:
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