簡體   English   中英

如何快速迭代一個大列表?

[英]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(...):然后用ielem分別將始終運行速度比for packed in enumerate(...):和使用packed[0]packed[1]如果你有超過有用的名稱ielem ,這將是啟動時更具可讀性)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM