sal*_*902 5 python performance list-comprehension list
假设我有一个列表:
list=['plu;ean;price;quantity','plu1;ean1;price1;quantity1']
Run Code Online (Sandbox Code Playgroud)
我想遍历列表+用“;”分割列表 并放置一个 if 子句,如下所示:
for item in list:
split_item=item.split(";")
if split_item[0] == "string_value" or split_item[1] == "string_value":
do something.....
Run Code Online (Sandbox Code Playgroud)
我想知道,这是否是最快的方法?假设我的初始列表要大得多(有更多的列表项)。我尝试使用列表理解:
item=[item.split(";") for item in list if item.split(";")[0] == "string_value" or item.split(";")[1] == "string_value"]
Run Code Online (Sandbox Code Playgroud)
但这实际上给了我较慢的结果。第一种情况平均为 90 毫秒,而第二种情况平均为 130 毫秒。我做的列表理解错了吗?有没有更快的解决方案?
如果您追求速度,hcwhsa 的答案应该足够好。如果您需要更多,请查看re。
import re
from itertools import chain
lis = ['plu;ean;price;quantity'*1000, 'plu1;ean1;price1;quantity1'*100]*1000
matcher = re.compile('^(?:plu(?:;|$)|[^;]*;ean(?:;|$))').match
[l.split(';') for l in lis if matcher(l)]
Run Code Online (Sandbox Code Playgroud)
时间,对于大多数积极的结果(又名。split是缓慢的主要原因):
SETUP="
import re
from itertools import chain
matcher = re.compile('^(?:plu(?:;|$)|[^;]*;ean(?:;|$))').match
lis = ['plu1;ean1;price1;quantity1'+chr(i) for i in range(10000)] + ['plu;ean;price;quantity' for i in range(10000)]
"
python -m timeit -s "$SETUP" "[[x] + [y] + z.split(';') for x, y, z in (item.split(';', 2) for item in lis) if x== 'plu' or y=='ean']"
python -m timeit -s "$SETUP" "[l.split(';') for l in lis if matcher(l)]"
Run Code Online (Sandbox Code Playgroud)
我们发现我的速度更快一些。
10 loops, best of 3: 55 msec per loop
10 loops, best of 3: 49.5 msec per loop
Run Code Online (Sandbox Code Playgroud)
对于大多数负面结果(大多数内容都被过滤):
SETUP="
import re
from itertools import chain
matcher = re.compile('^(?:plu(?:;|$)|[^;]*;ean(?:;|$))').match
lis = ['plu1;ean1;price1;quantity1'+chr(i) for i in range(1000)] + ['plu;ean;price;quantity' for i in range(10000)]
"
python -m timeit -s "$SETUP" "[[x] + [y] + z.split(';') for x, y, z in (item.split(';', 2) for item in lis) if x== 'plu' or y=='ean']"
python -m timeit -s "$SETUP" "[l.split(';') for l in lis if matcher(l)]"
Run Code Online (Sandbox Code Playgroud)
领先优势稍高一些。
10 loops, best of 3: 40.9 msec per loop
10 loops, best of 3: 35.7 msec per loop
Run Code Online (Sandbox Code Playgroud)
如果结果始终是唯一的,请使用
next([x] + [y] + z.split(';') for x, y, z in (item.split(';', 2) for item in lis) if x== 'plu' or y=='ean')
Run Code Online (Sandbox Code Playgroud)
或更快的正则表达式版本
next(filter(matcher, lis)).split(';')
Run Code Online (Sandbox Code Playgroud)
itertools.ifilter(在 Python 2 上使用)。
时间:
SETUP="
import re
from itertools import chain
matcher = re.compile('^(?:plu(?:;|$)|[^;]*;ean(?:;|$))').match
lis = ['plu1;ean1;price1;quantity1'+chr(i) for i in range(10000)] + ['plu;ean;price;quantity'] + ['plu1;ean1;price1;quantity1'+chr(i) for i in range(10000)]
"
python -m timeit -s "$SETUP" "[[x] + [y] + z.split(';') for x, y, z in (item.split(';', 2) for item in lis) if x== 'plu' or y=='ean']"
python -m timeit -s "$SETUP" "next([x] + [y] + z.split(';') for x, y, z in (item.split(';', 2) for item in lis) if x== 'plu' or y=='ean')"
python -m timeit -s "$SETUP" "[l.split(';') for l in lis if matcher(l)]"
python -m timeit -s "$SETUP" "next(filter(matcher, lis)).split(';')"
Run Code Online (Sandbox Code Playgroud)
结果:
10 loops, best of 3: 31.3 msec per loop
100 loops, best of 3: 15.2 msec per loop
10 loops, best of 3: 28.8 msec per loop
100 loops, best of 3: 14.1 msec per loop
Run Code Online (Sandbox Code Playgroud)
所以这对这两种方法都有很大的推动作用。