Sha*_*kan 71 python dictionary list
l = ["a", "b", "c", "d", "e"]
Run Code Online (Sandbox Code Playgroud)
我想将此列表转换为如下字典:
d = {"a": "b", "c": "d", "e": ""}
Run Code Online (Sandbox Code Playgroud)
所以基本上,均衡将是关键,而赔率将是价值.我知道我可以用"非pythonic"的方式来实现它,例如if语句的for循环,但我相信应该有更"pythonic"的方法来实现这一点.所以,我感谢任何帮助:)
nic*_*kl- 140
如果你还在想什么!你不会孤单,它实际上并不那么复杂,让我解释一下.
我们希望使用奇数条目(从1开始计数)将以下列表转换为字典,作为映射到其连续偶数条目的键.
l = ["a", "b", "c", "d", "e"]
Run Code Online (Sandbox Code Playgroud)
要创建字典,我们可以根据手册使用映射类型的内置dict函数,支持以下方法.
dict(one=1, two=2)
dict({'one': 1, 'two': 2})
dict(zip(('one', 'two'), (1, 2)))
dict([['two', 2], ['one', 1]])
Run Code Online (Sandbox Code Playgroud)
最后一个选项表明我们提供了包含2个值或(key, value)元组的列表列表,因此我们希望将顺序列表转换为:
l = [["a", "b"], ["c", "d"], ["e",]]
Run Code Online (Sandbox Code Playgroud)
我们还介绍了该zip功能,该手册解释了其中一个内置功能:
返回元组列表,其中第i个元组包含每个参数的第i个元素
换句话说,如果我们可以将列表转换为两个列表a, c, e,b, d那么zip将完成剩下的工作.
我们看到的切片与Strings一起使用,并且在List部分中进一步使用了切片主要使用范围或短切片符号,但这就是长切片符号的样子以及我们可以用步骤完成的事情:
>>> 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'}
Run Code Online (Sandbox Code Playgroud)
虽然这是理解所涉及的机制的最简单方法,但是存在一个缺点,因为切片每次都是新的列表对象,这可以从这个克隆示例中看出:
>>> a = [1, 2, 3]
>>> b = a
>>> b
[1, 2, 3]
>>> b is a
True
>>> b = a[:]
>>> b
[1, 2, 3]
>>> b is a
False
Run Code Online (Sandbox Code Playgroud)
尽管b现在看起来像是两个独立的物体,但这就是为什么我们更喜欢使用石斑鱼配方.
虽然石斑鱼被解释为itertools模块的一部分,但它与基本功能的完美结合.
一些严肃的伏都教吧?=)但实际上只不过是spice的一些语法糖,石斑鱼配方是通过以下表达式完成的.
*[iter(l)]*2
Run Code Online (Sandbox Code Playgroud)
或多或少转换为包含在列表中的同一迭代器的两个参数,如果这有意义的话.让我们分解它以帮助摆脱一些光.
>>> 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'}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的那样,两个迭代器的地址保持不变所以我们正在使用相同的迭代器,然后首先获取一个键,然后是一个值,一个键和一个值,每次步进相同的迭代器来完成我们所做的切片更有成效.
你会完成同样的事情,下面带有一个更小的东西是什么?因素也许.
>>> it = iter(l)
>>> dict(zip(it, it))
{'a': 'b', 'c': 'd'}
Run Code Online (Sandbox Code Playgroud)
e如果您注意到所有示例中都缺少了空键,那么因为zip选择了两个参数中最短的一个,所以我们该怎么做.
一个解决方案可能是在奇数长度列表中添加一个空值,你可以选择使用append和一个if可以做到这一点的语句,虽然有点无聊,对吧?
>>> if len(l) % 2:
... l.append("")
>>> l
['a', 'b', 'c', 'd', 'e', '']
>>> dict(zip(*[iter(l)]*2))
{'a': 'b', 'c': 'd', 'e': ''}
Run Code Online (Sandbox Code Playgroud)
现在,在你耸耸肩走向类型之前,from itertools import izip_longest你可能会惊讶地知道它不是必需的,我们可以完成同样的,甚至更好的恕我直言,仅内置功能.
我更喜欢使用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}
Run Code Online (Sandbox Code Playgroud)
正如KursedMetal所指出的那样,比较两种方法的性能,很明显,itertools模块远远超过了大量地图上的地图功能,作为1000万条记录显示的基准.
$ 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
Run Code Online (Sandbox Code Playgroud)
然而,导入模块的成本会对较小的数据集造成影响,当地图开始到达时,地图返回的速度要快得多,大约可达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
Run Code Online (Sandbox Code Playgroud)
什么都看不见!=)
的nJoy!
Sve*_*ach 46
使用通常的石斑鱼配方,您可以:
Python 2:
d = dict(itertools.izip_longest(*[iter(l)] * 2, fillvalue=""))
Run Code Online (Sandbox Code Playgroud)
Python 3:
d = dict(itertools.zip_longest(*[iter(l)] * 2, fillvalue=""))
Run Code Online (Sandbox Code Playgroud)
Gio*_*tro 18
我会去递归:
l = ['a', 'b', 'c', 'd', 'e', ' ']
d = dict([(k, v) for k,v in zip (l[::2], l[1::2])])
Run Code Online (Sandbox Code Playgroud)