Python:如何从键和值的普通列表构建字典

15

我有一个类似于以下的值列表:

["a", 1, "b", 2, "c", 3]

我想从中构建这样一个字典:

{"a": 1, "b": 2, "c": 3}

在Python中自然的方式是什么?


3
你是怎样得到这个列表的?创建该列表的循环应该被修复,直接创建字典。 - S.Lott
@S.Lott:列表是re.findall调用的结果。 - lithuak
1
请使用重要信息更新问题。这可能有助于保持原始的正则表达式,因为可能有简化处理的方法。 - S.Lott
5个回答

41
>>> x = ["a", 1, "b", 2, "c", 3]
>>> i = iter(x)
>>> dict(zip(i, i))
{'a': 1, 'c': 3, 'b': 2}

5
迭代对象的从左到右的计算顺序是有保证的。 - Josh Lee
1
谢谢,这就是正确的方式!我甚至将我的项目列表定义为x = (...)而不是[...],并且摆脱了显式的iter()调用。 - lithuak
1
@Josh:看起来你是对的,根据zip文档。那就+1吧 =) - cha0site
1
@izhak 明确调用iter函数以将列表分为两部分。请参阅 http://docs.python.org/library/itertools.html#itertools.izip 中的惯用法。 - Josh Lee
你可以用一行代码实现它:dict(zip(*[iter(x)]*2)) - Rik Poggi
1
@IvoFlipse: 你理解每个组件(iter、zip和dict)了吗?Iter非常简单:当你调用.next()时,它只会返回列表的下一个值。我编写了一个仅适用于两个参数的zip的简单实现:http://codepad.org/ywXjojYM尝试在脑海中将左右两侧替换为i,或者在每个步骤之间添加“print”来运行代码。 - André Paramés

14

这看起来相当简洁,但我不会说它很自然:

>>> l = ["a", 1, "b", 2, "c", 3]
>>> dict(zip(l[::2], l[1::2]))
{'a': 1, 'c': 3, 'b': 2}

3
您可以像这样压缩交替元素的列表: zip
>>> lst = ["a", 1, "b", 2, "c", 3]
>>> dict(zip(lst[::2], lst[1::2])
{'a': 1, 'c': 3, 'b': 2}

1

另一种方式:

>>> l = ["a", 1, "b", 2, "c", 3]
>>> dict([l[i:i+2] for i in range(0,len(l),2)])
{'a': 1, 'c': 3, 'b': 2}

0

我并不认为有很多情况会遇到这个确切的问题,因此没有“自然”的解决方案。但是,一个快速的一行代码应该可以解决你的问题:

   {input_list[2*i]:input_list[2*i+1] for i in range(len(input_list)//2)}

我怀疑这个会不会起作用。同时,不要使用内置名称(input)作为变量名。在Python 2.7中,它在for循环上失败,在Python 3中,它会抱怨range的参数是浮点数。 - Nobody moving away from SE
在发布之前尝试了Python 2.7.1。不确定它在其他版本中如何翻译。 - Bogdan
请查看http://ideone.com/K22Oa,http://ideone.com/XjKXl以及http://ideone.com/Q2RS1。 - Nobody moving away from SE
1
@Nobody:这在2.7中可以正常工作;你的ideone链接是到2.6的,它没有字典理解。将/更改为//也可以使其在3中工作。 - DSM
@DSM 是的,你说得对,我错误地记住了我的系统的Python版本为2.7.1(实际上是2.6.5),这就是我遇到错误的原因。正如我在第三个链接中所示,我已经设计了//的修正方法。这次讨论再次证明了我们在提供Python代码时应该始终给出版本号的重要性。 - Nobody moving away from SE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接