[英]Python: why is multiple list comprehensions seemingly faster than a single for loop with if...elif statements?
我有一些代碼,我試圖確定是否有更快的運行方法。 本質上,我有一個帶分隔符的文件,我正在迭代該文件以找到一組標志來解析數據。 這些文件可能很長,所以我試圖為此找到一種快速的方法。
我嘗試過的兩種方法是列表理解和 for 循環:
方法一:
flag_set_1 = [i for i,row in enumerate(data_file) if row[0] == flag_1]
flag_set_2 = [i for i,row in enumerate(data_file) if row[0] == flag_2]
flag_set_3 = [i for i,row in enumerate(data_file) if row[0] == flag_3]
flag_set_4 = [i for i,row in enumerate(data_file) if row[0] == flag_4]
方法二:
for i,row in enumerate(data_file):
if row[0] == flag_1:
flag_set_1.append(i)
elif row[0] == flag_2:
flag_set_2.append(i)
elif row[0] == flag_3:
flag_set_3.append(i)
elif row[0] == flag_4:
flag_set_4.append(i)
在這種情況下,我實際上期望列表理解會變慢。 認為方法 1 必須迭代 data_file 4 次,而方法 2 只需迭代一次。 我懷疑在方法 2 中使用 append() 是減慢速度的原因。
所以我問,有沒有更快的方法來實現這個?
沒有任何數據樣本或基准,也很難重現您的觀察結果。 我試過:
from random import randint
data_file = [[randint(0, 15) for _ in range(20)] for _ in range(100000)]
flag_1 = 1
flag_2 = 2
flag_3 = 3
flag_4 = 4
常規循環的速度是四個列表理解的兩倍(參見下面的基准)。
如果你想提高這個過程的速度,你有幾個線索。
如果flag_n
是字符串並且您確定row[0]
是每一row
中的其中一個,那么您可以檢查一個字符而不是整個字符串。 例如:
flag_1 = "first flag"
flag_2 = "second flag"
flag_3 = "third flag"
flag_4 = "fourth flag"
查看第二個字符: f<I>rst, S<E>cond, T<H>ird, F<O>urth
。 您只需要檢查row[0][1] == 'i'
(或'e'
或'h'
或'o'
)而不是row[0] == flag_n
。
如果你想提高常規循環的速度,你有幾個線索。
您可以分配flag = row[0]
而不是四次獲取row[0]
的第一個元素。 這是基本的,但它有效。
如果數據按標志排序,您顯然可以立即構建flag_n_set
:找到第一個最后一個flag_n
並編寫flag_n_set = list(range(first_flag_n_index, last_flag_n_index+1))
。
如果你知道標志的頻率,你可以命令if... elif... elif... elif... else
首先檢查更頻繁的標志,然后是第二頻繁的標志,等等。
您還可以使用 dict 來避免if... elif...
序列。 如果您沒有太多與任何標志不匹配的行,則可以使用defaultdict
:
from collections import defaultdict
def test_append_default_dict():
flag_set = defaultdict(list)
for i, row in enumerate(data_file):
flag_set[row[0]].append(i)
return tuple(flag_set[f] for f in (flag_1, flag_2, flag_3, flag_4))
以上數據的基准:
test_list_comprehensions 3.8617278739984613
test_append 1.9978336450003553
test_append_default_dict 1.4595633919998363
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.