[英]How can i iterate over a large list quickly?
我正在嘗試遍歷一個大列表。 我想要一種可以快速迭代此列表的方法。 但是迭代需要很多時間。 是否有任何方法可以快速迭代或沒有構建 python 來執行此操作。 我的代碼片段是:-
for i in THREE_INDEX:
if check_balanced(rc, pc):
print('balanced')
else:
rc, pc = equation_suffix(rc, pc, i)
這里THREE_INDEX的長度是117649,遍歷這個list需要很多時間,有沒有什么方法可以更快的遍歷。 但是迭代大概需要4-5分鍾
equation_suffix 函數:
def equation_suffix(rn, pn, suffix_list):
len_rn = len(rn)
react_suffix = suffix_list[: len_rn]
prod_suffix = suffix_list[len_rn:]
for re in enumerate(rn):
rn[re[0]] = add_suffix(re[1], react_suffix[re[0]])
for pe in enumerate(pn):
pn[pe[0]] = add_suffix(pe[1], prod_suffix[pe[0]])
return rn, pn
check_balanced 函數:
def check_balanced(rl, pl):
total_reactant = []
total_product = []
reactant_name = []
product_name = []
for reactant in rl:
total_reactant.append(separate_num(separate_brackets(reactant)))
for product in pl:
total_product.append(separate_num(separate_brackets(product)))
for react in total_reactant:
for key in react:
val = react.get(key)
val_dict = {key: val}
reactant_name.append(val_dict)
for prod in total_product:
for key in prod:
val = prod.get(key)
val_dict = {key: val}
product_name.append(val_dict)
reactant_name = flatten_dict(reactant_name)
product_name = flatten_dict(product_name)
for elem in enumerate(reactant_name):
val_r = reactant_name.get(elem[1])
val_p = product_name.get(elem[1])
if val_r == val_p:
if elem[0] == len(reactant_name) - 1:
return True
else:
return False
我相信“迭代”列表需要很長時間的原因是由於您在 for 循環中調用的方法。 我拿出方法只是為了測試迭代的速度,看來迭代一個117649大小的列表是非常快的。 這是我的測試腳本:
import time
start_time = time.time()
new_list = [(1, 2, 3) for i in range(117649)]
end_time = time.time()
print(f"Creating the list took: {end_time - start_time}s")
start_time = time.time()
for i in new_list:
pass
end_time = time.time()
print(f"Iterating the list took: {end_time - start_time}s")
輸出是:
Creating the list took: 0.005337953567504883s
Iterating the list took: 0.0035648345947265625s
編輯: time() 返回秒。
一般的for
循環不是問題,但使用它們來構建(或重建) list
通常比使用列表推導慢(或在某些情況下, map
/ filter
,盡管這些是通常令人悲觀的高級工具)。
通過這種方式,您的功能可以變得更加簡單,並且它們的啟動速度會更快。 示例重寫:
def equation_suffix(rn, pn, suffix_list):
prod_suffix = suffix_list[len(rn):]
# Change `rn =` to `rn[:] = ` if you must modify the caller's list as in your
# original code, not just return the modified list (which would be fine in your original code)
rn = [add_suffix(r, suffix) for r, suffix in zip(rn, suffix_list)] # No need to slice suffix_list; zip'll stop when rn exhausted
pn = [add_suffix(p, suffix) for p, suffix in zip(pn, prod_suffix)]
return rn, pn
def check_balanced(rl, pl):
# These can be generator expressions, since they're iterated once and thrown away anyway
total_reactant = (separate_num(separate_brackets(reactant)) for reactant in rl)
total_product = (separate_num(separate_brackets(product)) for product in pl)
reactant_name = []
product_name = []
# Use .items() to avoid repeated lookups, and concat simple listcomps to reduce calls to append
for react in total_reactant:
reactant_name += [{key: val} for key, val in react.items()]
for prod in total_product:
product_name += [{key: val} for key, val in prod.items()]
# These calls are suspicious, and may indicate optimizations to be had on prior lines
reactant_name = flatten_dict(reactant_name)
product_name = flatten_dict(product_name)
for i, (elem, val_r) in enumerate(reactant_name.items()):
if val_r == product_name.get(elem):
if i == len(reactant_name) - 1:
return True
else:
# I'm a little suspicious of returning False the first time a single
# key's value doesn't match. Either it's wrong, or it indicates an
# opportunity to write short-circuiting code that doesn't have
# to fully construct reactant_name and product_name when much of the time
# there will be an early mismatch
return False
我還會注意到,使用enumerate
而不解包結果會導致性能變差,並且代碼更加神秘; 在這種情況下(以及許多其他情況),不需要enumerate
,因為 listcomps 和 genexprs 可以在不知道索引的情況下完成相同的結果,但是在需要時,始終解壓縮,例如for i, elem in enumerate(...):
然后用i
和elem
分別將始終運行速度比for packed in enumerate(...):
和使用packed[0]
和packed[1]
如果你有超過有用的名稱i
和elem
,這將是啟動時更具可讀性)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.