15

我遇到过这个问题几次,似乎无法找到一个简单的解决方案。说我有一个字符串

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

我想将其转换为字典,其中 a、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])

所以我的问题是:有没有办法使用列表理解来消除 for 循环?如果没有,是否有一些内置的 python 方法可以为我做到这一点?

4

8 回答 8

29

你是这个意思吗?

>>> dict( (n,int(v)) for n,v in (a.split('=') for a in string.split() ) )
{'a': 0, 'c': 3, 'b': 1}
于 2009-08-07T19:07:15.993 回答
3

没有列表理解的单行如何?

 foo="a=0 b=1 c=3"
 ans=eval( 'dict(%s)'%foo.replace(' ',',')) )
 print ans
{'a': 0, 'c': 3, 'b': 1}
于 2009-08-08T01:50:16.683 回答
3

尝试下一个:

dict([x.split('=') for x in s.split()])
于 2009-08-08T14:17:31.037 回答
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()))
于 2009-08-08T14:50:23.167 回答
2

现在你可能应该使用 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
于 2014-11-20T07:13:58.557 回答
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}
于 2009-08-07T19:32:29.187 回答
0

我会这样做:

def kv(e): return (e[0], int(e[1]))
d = dict([kv(e.split("=")) for e in string.split(" ")])
于 2010-06-12T22:37:04.500 回答
-3

我喜欢 S.Lott 的解决方案,但我想出了另一种可能性。
由于您已经有一个类似于您编写方式的字符串,您可以将其调整为 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

这里的正则表达式非常原始,不会捕获所有可能的 python 标识符,但为了简单起见,我想保持简单。当然,如果您可以控制输入字符串的生成方式,只需根据 python 语法生成它并评估它即可。但是当然你应该执行额外的完整性检查以确保没有代码被注入那里!

于 2009-08-07T21:16:37.700 回答