15

我遇到過這個問題幾次,似乎無法找出一個簡單的解決方案。 說我有一個字符串將字符串轉換爲字典在Python中使用列表理解

string = "a=0 b=1 c=3" 

我想將其轉換成具有,b和c是所述鍵和0,1和3被它們各自的值的字典(轉換爲int)。很顯然,我可以這樣做:

list = string.split() 
    dic = {} 
    for entry in list: 
     key, val = entry.split('=') 
     dic[key] = int(val) 

但我真的不喜歡那個for循環,它似乎很簡單,你應該能夠將其轉換爲某種形式的名單理解的表達。這適用於val可以是字符串的稍微簡單的情況。

dic = dict([entry.split('=') for entry in list]) 

但是,我需要將val快速轉換爲int,並且執行類似這樣的操作在語法上是不正確的。

dic = dict([[entry[0], int(entry[1])] for entry.split('=') in list]) 

所以我的問題是:是否有消除使用列表理解循環的方法嗎?如果沒有,是否有一些內置的python方法可以爲我做到這一點?

+0

注:請不要使用內置函數作爲變量名('string','list'等) – 2010-09-03 04:48:59

回答

29

你的意思是?

>>> dict((n,int(v)) for n,v in (a.split('=') for a in string.split())) 
{'a': 0, 'c': 3, 'b': 1} 
+4

雖然這很酷,我覺得我更喜歡原來的問題的版本,從長遠代碼維護的觀點。原始問題中的代碼清晰明瞭,上面需要數十秒時間才能完成。 – 2009-08-07 21:28:37

+1

@Bryan Oakley:我同意。問題(「是否有一種方法可以消除使用列表理解的for循環」)有一個答案。但是,答案可能不是他們真正想要的。 – 2009-08-07 21:40:57

+1

是的,這就是我一直在尋找的。謝謝。 @Bryan:我開始認爲保持循環可能是一個好主意。儘管如此,至少現在我知道如何做到這一點。 – Pavel 2009-08-08 01:14:08

1
from cgi import parse_qsl 
text = "a=0 b=1 c=3" 
dic = dict((k, int(v)) for k, v in parse_qsl(text.replace(' ', '&'))) 
print dic 

打印

{'a': 0, 'c': 3, 'b': 1} 
+0

不錯......... 15。 – 2009-08-07 19:38:58

-3

我喜歡美國洛特的解決方案,但我想出了另一種可能性。
既然你已經有一個字符串類似不知爲何,你會寫的方式,你可以使其適應Python語法,然後eval()函數吧:)

import re 
string = "a=0 b=1 c=3" 
string2 = "{"+ re.sub('(|^)(?P<id>\w+)=(?P<val>\d+)', ' "\g<id>":\g<val>,', string) +"}" 
dict = eval(string2) 
print type(string), type(string2), type(dict) 
print string, string2, dict 

這裏的正則表達式是相當原始,並榮獲」 t捕獲所有可能的Python標識符,但爲了簡單起見,我想保持簡單。 當然,如果您可以控制輸入字符串的生成方式,只需根據python語法生成並將其評估即可。 但是,當然你應該執行額外的理智檢查,以確保沒有代碼注入那裏!

+2

你想保持這個簡單?不要吝嗇或挑選任何人,但這在哪裏很簡單? – Nope 2009-08-08 22:22:24

3

單線程沒有列表理解的情況如何?

foo="a=0 b=1 c=3" 
ans=eval('dict(%s)'%foo.replace(' ',','))) 
print ans 
{'a': 0, 'c': 3, 'b': 1} 
+0

我知道eval如何工作,但我很難理解這個 – Ajay 2015-05-01 10:28:28

+1

foo.replace()將「a = 0 b = 1 c = 3」變成「a = 0,b = 1,c = 3」。字符串格式創建一個新的字符串「dict(a = 0,b = 1,c = 3)」。評估該字符串產生所需的字典。 – 2015-05-05 01:44:23

+0

我花了一段時間才明白.. – Ajay 2015-05-05 05:53:13

3

嘗試了下:

dict([x.split('=') for x in s.split()]) 
+1

OP想要將列表中的第二個元素轉換爲整數。 – hughdbrown 2009-08-08 15:11:29

2

我有時喜歡這種方法,尤其是在製作鍵和值的邏輯比較複雜:

s = "a=0 b=1 c=3" 

def get_key_val(x): 
    a,b = x.split('=') 
    return a,int(b) 

ans = dict(map(get_key_val,s.split())) 
0

我這樣做:

def kv(e): return (e[0], int(e[1])) 
d = dict([kv(e.split("=")) for e in string.split(" ")]) 
2

現在你s HOULD可能使用字典理解,在2.7介紹:

mydict = {key: int(value) for key, value in (a.split('=') for a in mystring.split())} 

的字典解析速度更快,更亮澤(和,在我看來,更具可讀性)。

from timeit import timeit 

setup = """mystring = "a=0 b=1 c=3\"""" 
code1 = """mydict = dict((n,int(v)) for n,v in (a.split('=') for a in mystring.split()))""" # S.Lott's code 
code2 = """mydict = {key: int(value) for key, value in (a.split('=') for a in mystring.split())}""" 

print timeit(code1, setup=setup, number=10000) # 0.115524053574 
print timeit(code2, setup=setup, number=10000) # 0.105328798294 
相關問題