Python - 在dict理解中解组的元组

时间:2012-08-23 15:08:14

标签: python dictionary iterable-unpacking dictionary-comprehension

我正在尝试编写一个函数,将'A=5, b=7'形式的字符串转换为dict {'A': 5, 'b': 7}。以下代码片段是主for循环中发生的内容 - 它们将字符串的单个部分转换为单个dict元素。

这很好:

s = 'A=5'
name, value = s.split('=')
d = {name: int(value)}

这不是:

s = 'A=5'
d = {name: int(value) for name, value in s.split('=')}
ValueError: need more than 1 value to unpack

为什么我不能在字典理解中解包元组?如果我得到这个工作,那么我可以很容易地将整个功能变成一个紧凑的字典理解。

7 个答案:

答案 0 :(得分:18)

在您的代码中,s.split('=')将返回列表:['A', '5']。迭代该列表时,每次返回一个字符串(第一次为'A',第二次为'5'),因此您无法将该单个字符串解包为2个变量。< / p>

您可以尝试:for name,value in [s.split('=')]

更有可能的是,你有一个想要分割的字符串的迭代 - 然后你的字典理解变得简单(2行):

 splitstrs = (s.split('=') for s in list_of_strings) 
 d = {name: int(value) for name,value in splitstrs }

当然,如果你沉迷于1-liners,你可以把它结合起来,但我不会。

答案 1 :(得分:6)

当然可以这样做:

>>> s = 'A=5, b=7'
>>> {k: int(v) for k, v in (item.split('=') for item in s.split(','))}
{'A': 5, ' b': 7}

但在这种情况下,我会使用这个更强制性的代码:

>>> d = {}
>>> for item in s.split(','):
        k, v = item.split('=')
        d[k] = int(v)


>>> d
{'A': 5, ' b': 7}

答案 2 :(得分:5)

有些人倾向于相信你会因使用eval而下地狱,但......

s = 'A=5, b=7'
eval('dict(%s)' % s)

或者更好,为了安全(感谢mgilson指出):

s = 'A=5, b=7'
eval('dict(%s)' % s, {'__builtins__': None, 'dict': dict})

答案 3 :(得分:2)

这段代码怎么样:

a="A=5, b=9"
b=dict((x, int(y)) for x, y in re.findall("([a-zA-Z]+)=(\d+)", a))
print b

输出:

{'A': 5, 'b': 9}

此版本也适用于其他形式的输入,例如

a="A=5 b=9 blabla: yyy=100"

会给你

{'A': 5, 'b': 9, 'yyy': 100}

答案 4 :(得分:2)

请参阅mgilson回答错误发生的原因。要实现您的目标,您可以使用:

d = {name: int(value) for name,value in (x.split('=',1) for x in s.split(','))}

要考虑空格,请根据需要使用.strip()(例如:x.strip().split('=',1))。

答案 5 :(得分:2)

>>> strs='A=5, b=7'

>>> {x.split('=')[0].strip():int(x.split('=')[1]) for x in strs.split(",")}
{'A': 5, 'b': 7}

为了便于阅读,你应该使用普通的for-in循环而不是理解。

strs='A=5, b=7'
dic={}
for x in strs.split(','):
  name,val=x.split('=')
  dic[name.strip()]=int(val)

答案 6 :(得分:0)

这个怎么样?

>>> s
'a=5, b=3, c=4'
>>> {z.split('=')[0].strip(): int(z.split('=')[1]) for z in s.split(',')}
{'a': 5, 'c': 4, 'b': 3}