これは私が数分で作り上げたものです。この関数は、所定の場所にあるリストを変更し、連続する繰り返しを削除します。
def make_unique(lst):
if len(lst) <= 1:
return lst
last = lst[-1]
for i in range(len(lst) - 2, -1, -1):
item = lst[i]
if item == last:
del lst[i]
else:
last = item
いくつかの代表的な入力データ:
inp = [
(u"Tomato", "de"), (u"Cherry", "en"), (u"Watermelon", None), (u"Apple", None),
(u"Cucumber", "de"), (u"Lettuce", "de"), (u"Tomato", None), (u"Banana", None),
(u"Squash", "en"), (u"Rubarb", "de"), (u"Lemon", None),
]
両方のバリアントが希望どおりに機能することを確認します。
print inp
print sorted(set(inp))
# copy because we want to modify it in place
inp1 = inp[:]
inp1.sort()
make_unique(inp1)
print inp1
次に、テストを行います。リストのコピーの時間を計りたくないので、timeitを使用していません。ソートのみを行っています。time1
はsorted(set(...)
、の後に、time2
がlist.sort()
続きmake_unique
、はAvinashYによるtime3
解です。itertools.groupby
import time
def time1(number):
total = 0
for i in range(number):
start = time.clock()
sorted(set(inp))
total += time.clock() - start
return total
def time2(number):
total = 0
for i in range(number):
inp1 = inp[:]
start = time.clock()
inp1.sort()
make_unique(inp1)
total += time.clock() - start
return total
import itertools
def time3(number):
total = 0
for i in range(number):
start = time.clock()
list(k for k,_ in itertools.groupby(sorted(inp)))
total += time.clock() - start
return total
sort + make_unique
とほぼ同じ速さsorted(set(...))
です。どちらが潜在的に高速であるかを確認するには、さらに2、3回の反復を行う必要がありますが、バリエーション内では非常に似ています。バージョンはitertools
少し遅いです。
# done each 3 times
print time1(100000)
# 2.38, 3.01, 2.59
print time2(100000)
# 2.88, 2.37, 2.6
print time3(100000)
# 4.18, 4.44, 4.67
より大きなリストがあります(+ str(i)
重複を防ぐためです):
old_inp = inp[:]
inp = []
for i in range(100):
for j in old_inp:
inp.append((j[0] + str(i), j[1]))
print time1(10000)
# 40.37
print time2(10000)
# 35.09
print time3(10000)
# 40.0
リストに重複がたくさんある場合は、最初のバージョンの方がはるかに高速であることに注意してください(ソートが少ないため)。
inp = []
for i in range(100):
for j in old_inp:
#inp.append((j[0] + str(i), j[1]))
inp.append((j[0], j[1]))
print time1(10000)
# 3.52
print time2(10000)
# 26.33
print time3(10000)
# 20.5