General for
циклы не проблема, но их использование для построения (или перестройки) list
s обычно медленнее, чем использование списочных представлений (или в некоторых случаях 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
без распаковки результата приведет к ухудшению производительности и увеличению количества крипт c кода; в этом случае (и во многих других) enumerate
не требуется, так как listcomps и genexprs могут достичь sh того же результата, не зная индекса, но когда это необходимо, всегда распаковывать, например, for i, elem in enumerate(...):
, затем использовать i
и elem
по отдельности всегда будут работать быстрее, чем for packed in enumerate(...):
и с использованием packed[0]
и packed[1]
(и если у вас будет больше полезных имен, чем i
и elem
, загрузка будет намного более удобной для чтения ).