import string
a , b , c = string.ascii_lowercase , string.ascii_uppercase , string.digits
l1 = [ (i , a ,b , c ,) for i in range(100,1000000) ] #all
l2 = [ (i,) for i in range(150,340192) ] # used
x = [
item for item in l1 if (item[0],) not in l2
]
print(len(x)) # it costs at least 50 seconds to run
我正在尋求改進我的代碼或使其更快。
uj5u.com熱心網友回復:
l2是單例元組的串列(一個非常大的串列),您檢查成員資格。由于您正在檢查成員資格,因此將其設定為一組會更有效率。
# construct a set from the range
s_l2 = set(range(150,340192))
# check for set membership
x = [item for item in l1 if item[0] not in s_l2]
基準:
%timeit x = [item for item in l1 if (item[0],) not in l2]
# 6.55 s ± 326 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit y = [item for item in l1 if item[0] not in range(150,340192)]
# 4.22 s ± 56.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit s_l2 = set(range(150,340192)); z = [item for item in l1 if item[0] not in s_l2]
#141 ms ± 3.51 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
uj5u.com熱心網友回復:
簡單的思路是直接判斷每個元素是否在rangewithout generate中l2:
>>> r = range(150, 340192)
>>> timeit(lambda: [item for item in [(i, a, b, c) for i in range(100,1000000)] if item[0] not in r], number=7)
1.5238849000015762
也可以通過對比直接簡化:
>>> timeit(lambda: [item for item in [(i, a, b, c) for i in range(100,1000000)] if not 150 <= item[0] < 340192], number=7)
1.341257099993527
最簡單的方法是預先構建目標范圍,然后在一次回圈中生成目標串列:
>>> from itertools import chain
>>> timeit(lambda: [(i, a, b, c) for i in chain(range(100, 150), range(340192, 1000000))], number=7)
0.5550074999919161
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/487287.html
