簡體   English   中英

從字符串創建python字典的最佳方法是什么?

[英]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

編輯:隨着需求的細微變化,我試過findalloptionC ,並略有不同版本的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.

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