我正在尝试遍历一个大列表。我想要一种可以快速迭代此列表的方法。但是要花很多时间进行迭代。是否有任何快速迭代的方法,或者没有构建python来执行此操作。 我的代码段是:-
for i in THREE_INDEX:
if check_balanced(rc, pc):
print('balanced')
else:
rc, pc = equation_suffix(rc, pc, i)
此处THREE_INDEX的长度为117649。在此列表上进行迭代需要花费大量时间,是否有任何方法可以更快地对其进行迭代。但是要花大约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
答案 0 :(得分:2)
我相信“迭代”列表需要很长时间的原因是由于您在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()返回第二个。
答案 1 :(得分:1)
一般的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
,引导起来更具可读性。