python转换列表字典

l = ["a", "b", "c", "d", "e"] 

我想将这个列表转换成一个字典,如:

 d = {"a": "b", "c": "d", "e": ""} 

所以基本上,平衡是关键,而赔率是价值。 我知道我可以用“非pythonic”的方式来做,比如if语句的for循环,但我相信应该有一个更“pythonic”的方法来完成这个。 所以,我感谢任何帮助:)

使用通常的石斑鱼配方 ,你可以做:

Python 2:

 d = dict(itertools.izip_longest(*[iter(l)] * 2, fillvalue="")) 

Python 3:

 d = dict(itertools.zip_longest(*[iter(l)] * 2, fillvalue="")) 

如果你还在想什么! 你不会一个人,其实并不那么复杂,让我解释一下。

如何仅使用内置函数将列表转换为字典

我们想把下面的列表变成一个字典,使用奇数条目(从1开始)作为映射到它们连续的偶数条目的关键字。

 l = ["a", "b", "c", "d", "e"] 

字典()

要创build一个字典,我们可以使用内置的dictfunction的映射types按照手册支持以下方法。

 dict(one=1, two=2) dict({'one': 1, 'two': 2}) dict(zip(('one', 'two'), (1, 2))) dict([['two', 2], ['one', 1]]) 

最后一个选项build议我们提供一个带有2个值或(key, value)元组的列表,所以我们想把我们的顺序列表变成:

 l = [["a", "b"], ["c", "d"], ["e",]] 

我们还介绍了zip函数,这是手册解释的内置函数之一 :

返回一个元组列表,其中第i个元组包含每个参数的第i个元素

换句话说,如果我们可以将我们的列表变成两个列表a, c, eb, d那么zip将完成剩下的工作。

切片符号

我们看到用于string的切片 ,还有主要使用范围短切片符号的List部分 ,但是这是长切片符号的样子,我们可以用step来完成:

 >>> l[::2] ['a', 'c', 'e'] >>> l[1::2] ['b', 'd'] >>> zip(['a', 'c', 'e'], ['b', 'd']) [('a', 'b'), ('c', 'd')] >>> dict(zip(l[::2], l[1::2])) {'a': 'b', 'c': 'd'} 

尽pipe这是理解所涉及的机制的最简单的方法,但是由于片每次都是新的列表对象,所以存在不足,正如可以看到的克隆示例:

 >>> a = [1, 2, 3] >>> b = a >>> b [1, 2, 3] >>> b is a True >>> b = a[:] >>> b [1, 2, 3] >>> b is a False 

尽pipeb看起来像是一个,但是现在它们是两个单独的对象,这就是为什么我们更喜欢使用石斑鱼配方 。

石斑鱼食谱

虽然石斑鱼被解释为itertools模块的一部分,但它的基本function也完全正常。

一些严重的伏都教吧? =)但实际上只不过是一些糖的香料,石斑鱼配方是由下面的expression式完成。

 *[iter(l)]*2 

如果这是有道理的,那么它或多或less会转换成包含在列表中的相同迭代器的两个参数。 让我们分解一下,以帮助解决一些问题。

邮编最短

 >>> l*2 ['a', 'b', 'c', 'd', 'e', 'a', 'b', 'c', 'd', 'e'] >>> [l]*2 [['a', 'b', 'c', 'd', 'e'], ['a', 'b', 'c', 'd', 'e']] >>> [iter(l)]*2 [<listiterator object at 0x100486450>, <listiterator object at 0x100486450>] >>> zip([iter(l)]*2) [(<listiterator object at 0x1004865d0>,),(<listiterator object at 0x1004865d0>,)] >>> zip(*[iter(l)]*2) [('a', 'b'), ('c', 'd')] >>> dict(zip(*[iter(l)]*2)) {'a': 'b', 'c': 'd'} 

正如你所看到的,这两个迭代器的地址保持不变,所以我们使用相同的迭代器,然后首先从zip获取一个键,然后每次使用相同的迭代器来完成我们所做的操作,然后返回一个值和一个键和一个值切片更有成效。

你会完成很多与以下哪个进行更小的什么? 因素也许。

 >>> it = iter(l) >>> dict(zip(it, it)) {'a': 'b', 'c': 'd'} 

如果你注意到所有的例子都没有,那么空键是什么?因为zipselect了最短的两个参数,所以我们该怎么做。

那么一种解决scheme可能是将一个空值添加到奇数长度的列表中,你可以select使用appendif语句,尽pipe有点无聊,对吧?

 >>> if len(l) % 2: ... l.append("") >>> l ['a', 'b', 'c', 'd', 'e', ''] >>> dict(zip(*[iter(l)]*2)) {'a': 'b', 'c': 'd', 'e': ''} 

现在,在你摆脱from itertools import izip_longesttypesfrom itertools import izip_longest你可能会惊讶地发现它不是必需的,我们可以完成同样的,甚至更好的恕我直言,单独的内置function。

地图最长

我更喜欢使用map()函数而不是izip_longest() ,它不仅使用较短的语法,而且不需要导入,但可以根据需要自动分配一个实际的None空值。

 >>> l = ["a", "b", "c", "d", "e"] >>> l ['a', 'b', 'c', 'd', 'e'] >>> dict(map(None, *[iter(l)]*2)) {'a': 'b', 'c': 'd', 'e': None} 

正如KursedMetal指出的那样,比较两种方法的性能,很明显itertools模块远远优于大数据量的map函数,以1000万条logging为基准。

 $ time python -c 'dict(map(None, *[iter(range(10000000))]*2))' real 0m3.755s user 0m2.815s sys 0m0.869s $ time python -c 'from itertools import izip_longest; dict(izip_longest(*[iter(range(10000000))]*2, fillvalue=None))' real 0m2.102s user 0m1.451s sys 0m0.539s 

然而,导入模块的成本对较小的数据集造成了代价,当地图开始到达时,地图返回速度会快得多,达到大约10万条。

 $ time python -c 'dict(map(None, *[iter(range(100))]*2))' real 0m0.046s user 0m0.029s sys 0m0.015s $ time python -c 'from itertools import izip_longest; dict(izip_longest(*[iter(range(100))]*2, fillvalue=None))' real 0m0.067s user 0m0.042s sys 0m0.021s $ time python -c 'dict(map(None, *[iter(range(100000))]*2))' real 0m0.074s user 0m0.050s sys 0m0.022s $ time python -c 'from itertools import izip_longest; dict(izip_longest(*[iter(range(100000))]*2, fillvalue=None))' real 0m0.075s user 0m0.047s sys 0m0.024s 

一无所获! =)

的nJoy!

我会去recursion:

 l = ['a', 'b', 'c', 'd', 'e', ' '] d = dict([(k, v) for k,v in zip (l[::2], l[1::2])]) 

不知道它是否会帮助你,但它对我有用:

 l = ["a", "b", "c", "d", "e"] outRes = dict((l[i], l[i+1]) if i+1 < len(l) else (l[i], '') for i in xrange(len(l)))