python 使用列表理解将字符串转换为字典

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1246444/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:46:34  来源:igfitidea点击:

convert string to dict using list comprehension

pythonstringdictionarylist-comprehensiongenerator-expression

提问by Pavel

I have came across this problem a few times and can't seem to figure out a simple solution. Say I have a string

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

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

I want to convert that into a dictionary with a, b and c being the key and 0, 1, and 3 being their respective values (converted to int). Obviously I can do this:

我想将其转换为字典,其中 a、b 和 c 是键,0、1 和 3 是它们各自的值(转换为 int)。显然我可以这样做:

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

But I don't really like that for loop, It seems so simple that you should be able to convert it to some sort of list comprehension expression. And that works for slightly simpler cases where the valcan be a string.

但我真的不喜欢那个 for 循环,它看起来很简单,你应该能够将它转换为某种列表理解表达式。这适用于val可以是字符串的稍微简单的情况。

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

However, I need to convert val to an int on the fly and doing something like this is syntactically incorrect.

但是,我需要即时将 val 转换为 int 并且这样做在语法上是不正确的。

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

So my question is: is there a way to eliminate the for loop using list comprehension? If not, is there some built in python method that will do that for me?

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

回答by S.Lott

Do you mean this?

你是这个意思吗?

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

回答by Vicki Laidler

How about a one-liner without list comprehension?

没有列表理解的单行怎么样?

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

回答by Vicki Laidler

Try the next:

尝试下一个:

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

回答by Vicki Laidler

I sometimes like this approach, especially when the logic for making keys and values is more complicated:

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

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()))

回答by dantiston

Nowadays you should probably use a dictionary comprehension, introduced in 2.7:

现在你可能应该使用字典理解,在 2.7 中引入:

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

The dictionary comprehension is faster and shinier (and, in my opinion, more readable).

字典理解更快、更亮(而且,在我看来,更具可读性)。

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

回答by nosklo

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

prints

印刷

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

回答by Tadhg

I would do this:

我会这样做:

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

回答by Agos

I like S.Lott's solution, but I came up with another possibility.
Since you already have a string resembling somehow the way you'd write that, you can just adapt it to python syntax and then eval() it :)

我喜欢 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

The regex here is pretty raw and won't catch all the possible python identifiers, but I wanted to keep it simple for simplicity's sake. Of course if you have control over how the input string is generated, just generate it according to python syntax and eval it away. BUT of course you should perform additional sanity checks to make sure that no code is injected there!

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