Mik*_*rns 8 python zip dictionary
当map
具有不同长度的输入时,填充值None
用于缺少的输入:
>>> x = [[1,2,3,4],[5,6]]
>>> map(lambda *x:x, *x)
[(1, 5), (2, 6), (3, None), (4, None)]
Run Code Online (Sandbox Code Playgroud)
这与以下行为相同:
>>> import itertools
>>> list(itertools.izip_longest(*x))
[(1, 5), (2, 6), (3, None), (4, None)]
Run Code Online (Sandbox Code Playgroud)
是什么原因导致map
了这种行为,而不是以下情况?
>>> map(lambda *x:x, *x)
[(1, 5), (2, 6), (3,), (4,)]
Run Code Online (Sandbox Code Playgroud)
...并有一个简单的方法来获得后者的行为或者与一些味道zip
还是map
?
我认为这是核心开发人员在实施时选择的设计决策map
.map
当它与多个迭代一起使用时,没有普遍定义的行为,引用Map(高阶函数):
当列表具有不同长度时,具有2个或更多列表的映射遇到处理问题.各种语言不同; 一些引发异常,一些在最短列表的长度后停止并忽略其他列表中的额外项目; 一些继续到最长列表的长度,对于已经结束的列表,将一些占位符值传递给函数,指示没有值.
因此,Python核心开发人员在1993年选择None
用作较短迭代的占位符,于1993年map
被引入 Python.
但是,如果itertools.imap
它的短路具有最短的可迭代性,因为它的设计受到标准ML,Haskell和APL等语言的大量启发.在标准ML和Haskell map
以最短的可迭代结束(虽然我不确定APL).
Python 3还删除了map(None, ...)
(或者我们应该说itertools.imap
,Python 3 map
实际上几乎就是itertools.imap
:从中移动到map()
itertools
builtins
)构造,因为它只存在于Python 2中,因为当时map
已经添加到Python中,Python中没有zip()
函数.
来自Issue2186:map
并且filter
不应该支持None
作为第一个参数(仅在Py3k中):
我赞同Guido,
map(None, ...)
如果zip()
存在的话 ,我们永远不会创造.主要用例已过时.
为了获得你想要的结果我建议使用itertools.izip_longest
sentinel值(object()
)而不是默认值None
,None
如果iterables本身包含None
:
from itertools import izip_longest
def solve(seq):
sentinel = object()
return [tuple(x for x in item if x is not sentinel) for item in
izip_longest(*seq, fillvalue=sentinel)]
print solve([[1,2,3,4],[5,6]])
# [(1, 5), (2, 6), (3,), (4,)]
Run Code Online (Sandbox Code Playgroud)