[英]What is the best way to create a python dictionary from a string?
我有一個大文件,我將在其中解析約1.9E8行。
在每次迭代期間,我將創建一個臨時字典以發送給另一個方法,這將為我提供所需的輸出。
由於文件太大,因此無法使用readlines()方法打開它。
因此,我想加快速度的最后一招就是在解析過程中。
我已經有兩個選擇來生成字典。 optionB具有比optionA更好的性能,並且我知道我可以嘗試使用正則表達式,但是我並不熟悉它。 如果有的話,我願意得到更好的替代方案的見解。
預期的輸入: "A@1:100;2:240;...:.."
輸入可能會更長,可能會有更多的組及其頻率
def optionA(line):
_id, info = line.split("@")
data = {}
for g_info in info.split(";"):
k, v = g_info.split(":")
data[k] = v
return data
def optionB(line):
_id, info = line.split("@")
return dict(map(lambda i: i.split(":"), info.split(";")))
預期輸出: {'1': '100', '2': '240'}
我願意接受任何建議!
正則表達式解析行的快速示例:
>>> import re
>>> line = 'A@1:100;2:240'
>>> data = re.search(r'@(\d+):(\d+);(\d+):(\d+)',line).groups()
>>> D = {data[0]:data[1],data[2]:data[3]}
>>> D
{'1': '100', '2': '240'}
以下是一些時間安排:
import re
regex = re.compile(r'@(\d+):(\d+);(\d+):(\d+)')
def optionA(line):
_id, info = line.split("@")
data = {}
for g_info in info.split(";"):
k, v = g_info.split(":")
data[k] = v
return data
def optionB(line):
_id, info = line.split("@")
return dict(map(lambda i: i.split(":"), info.split(";")))
def optionC(line):
data = regex.search(line).groups()
return {data[0]:data[1],data[2]:data[3]}
line = 'A@1:100;2:240'
時間:
C:\>py -m timeit -s "import x" "x.optionA(x.line)"
100000 loops, best of 3: 3.01 usec per loop
C:\>py -m timeit -s "import x" "x.optionB(x.line)"
100000 loops, best of 3: 5.15 usec per loop
C:\>py -m timeit -s "import x" "x.optionC(x.line)"
100000 loops, best of 3: 2.88 usec per loop
編輯:隨着需求的細微變化,我試過findall
為optionC
,並略有不同版本的optionA
:
import re
regex = re.compile(r'(\d+):(\d+)')
def optionA(line):
_id, info = line.split("@")
data = {}
for g_info in info.split(";"):
k, v = g_info.split(":")
data[k] = v
return data
def optionAA(line):
data = {}
for g_info in line[2:].split(";"):
k, v = g_info.split(":")
data[k] = v
return data
def optionB(line):
_id, info = line.split("@")
return dict(map(lambda i: i.split(":"), info.split(";")))
def optionC(line):
return dict(regex.findall(line))
line = 'A@1:100;2:240;3:250;4:260;5:100;6:100;7:100;8:100;9:100;10:100'
時間:
C:\>py -m timeit -s "import x" "x.optionA(x.line)"
100000 loops, best of 3: 8.35 usec per loop
C:\>py -m timeit -s "import x" "x.optionAA(x.line)"
100000 loops, best of 3: 8.17 usec per loop
C:\>py -m timeit -s "import x" "x.optionB(x.line)"
100000 loops, best of 3: 12.3 usec per loop
C:\>py -m timeit -s "import x" "x.optionC(x.line)"
100000 loops, best of 3: 12.8 usec per loop
因此,看起來經過修改的optionAA
贏得了這條特殊的線。 希望這顯示了測量算法的重要性。 令我感到驚訝的是findall
速度慢一些。
這是一個使用已編譯的正則表達式來匹配您的模式的簡單示例。
import re
s = "A@1:100;2:240"
compiledre = re.compile("A@(\d+):(\d+);(\d+):(\d+)$")
res = compiledre.search(s)
if res:
print dict([(res.group(1),res.group(2)),(res.group(3),res.group(4))])
輸出為:
{'1': '100', '2': '240'}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.