Python 使用列表理解将字符串转换为dict

Python 使用列表理解将字符串转换为dict,python,string,dictionary,list-comprehension,generator-expression,Python,String,Dictionary,List Comprehension,Generator Expression,我曾多次遇到这个问题,似乎无法找到简单的解决方案。 说我有一根绳子 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) 但我不太喜欢循环,它看起来很简单,你应该能够把它转换成某种

我曾多次遇到这个问题,似乎无法找到简单的解决方案。 说我有一根绳子

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)
但我不太喜欢循环,它看起来很简单,你应该能够把它转换成某种列表理解表达式。这适用于稍微简单的情况,
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方法可以为我做到这一点?

你的意思是

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

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

我喜欢S.Lott的解决方案,但我提出了另一种可能性。
因为您已经有了一个类似于您编写它的方式的字符串,所以您可以将它调整为python语法,然后eval()它:)

重新导入
string=“a=0 b=1 c=3”
string2=“{”+re.sub('(|^)(?P\w+=(?P\d+),'“\g”:\g',string)+”}”
dict=评估(string2)
打印类型(字符串)、类型(字符串2)、类型(dict)
打印字符串,字符串2,dict
这里的正则表达式非常原始,不会捕获所有可能的python标识符,但为了简单起见,我希望保持它的简单性。 当然,如果您可以控制输入字符串的生成方式,只需根据python语法生成它并对其求值即可。
但当然,您应该执行额外的健全性检查,以确保没有代码被注入其中

一行没有列表理解的怎么样

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

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

我有时喜欢这种方法,尤其是当制作键和值的逻辑更复杂时:

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()))
我会这样做:

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

现在,您可能应该使用2.7中介绍的字典理解:

mydict = {key: int(value) for key, value in (a.split('=') for a in mystring.split())}
字典的理解速度更快,更清晰(在我看来,更可读)


虽然这很酷,但从长期代码维护的角度来看,我更喜欢原始问题中的版本。原始问题中的代码是清楚明了的,上面的代码需要几十秒才能完成。@布赖恩·奥克利:我同意。这个问题(“是否有一种使用列表理解消除for循环的方法”)有一个答案。但是,答案可能不是他们真正想要的。OP希望列表中的第二个元素转换为整数。您想保持这个简单吗?不要吝啬或挑剔任何人,但这到底是怎么回事?注意:不要将内置函数用作变量名(
string
list
,等等)。foo.replace()将“a=0 b=1 c=3”转换为“a=0,b=1,c=3”。字符串格式将创建一个新字符串“dict(a=0,b=1,c=3)”。求值该字符串将生成所需的dict。
def kv(e): return (e[0], int(e[1]))
d = dict([kv(e.split("=")) for e in string.split(" ")])
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