如何快速遍历大量清单?

时间:2020-03-11 15:29:45

标签: python python-3.x list

我正在尝试遍历一个大列表。我想要一种可以快速迭代此列表的方法。但是要花很多时间进行迭代。是否有任何快速迭代的方法,或者没有构建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

2 个答案:

答案 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(...):然后分别使用ielem总是比for packed in enumerate(...):并使用packed[0]packed[1]运行速度更快(如果您有更有用的名称,比起ielem,引导起来更具可读性。