the*_*olf 19 python python-3.x map-function
在Python 2中,一个常见的(旧的,遗留的)习惯用于使用map如下形式连接不均匀长度的迭代器map(None,iter,iter,...):
>>> map(None,xrange(5),xrange(10,12))
[(0, 10), (1, 11), (2, None), (3, None), (4, None)]
Run Code Online (Sandbox Code Playgroud)
在Python 2中,它被扩展,以便最长的迭代器是返回列表的长度,如果一个比另一个短,则用它填充None.
在Python 3中,这是不同的.首先,你不能None用作位置1中可调用的参数:
>>> list(map(None, range(5),range(10,12)))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
Run Code Online (Sandbox Code Playgroud)
好的 - 我可以解决这个问题:
>>> def f(*x): return x
...
>>> list(map(f, *(range(5),range(10,12))))
[(0, 10), (1, 11)]
Run Code Online (Sandbox Code Playgroud)
但现在,我有一个不同的问题:map返回最短迭代器的长度 - 不再填充None.
当我将Python 2代码移植到Python 3时,这不是一个非常罕见的习惯用法,我还没有找到一个简单易用的解决方案.
不幸的是,2to3的工具,不挑这件事-帮倒忙提示:
-map(None,xrange(5),xrange(10,18))
+list(map(None,list(range(5)),list(range(10,18))))
Run Code Online (Sandbox Code Playgroud)
建议?
编辑
有一些讨论这个成语有多常见.看到这篇SO帖子.
我正在更新我还在高中时写的遗留代码.看看Raymond Hettinger 编写和讨论的2003 Python教程,指出了这个特定的地图行为......
Dou*_*gal 18
itertools.zip_longest以更易于理解的名义做你想做的事.:)
这次我会回答我自己的问题。
对于 Python 3x,您可以像这样使用itertools.zip_longest :
>>> list(map(lambda *a: a,*zip(*itertools.zip_longest(range(5),range(10,17)))))
[(0, 10), (1, 11), (2, 12), (3, 13), (4, 14), (None, 15), (None, 16)]
Run Code Online (Sandbox Code Playgroud)
我想你也可以自己推出:
>>> def oldMapNone(*ells):
... '''replace for map(None, ....), invalid in 3.0 :-( '''
... lgst = max([len(e) for e in ells])
... return list(zip(* [list(e) + [None] * (lgst - len(e)) for e in ells]))
...
>>> oldMapNone(range(5),range(10,12),range(30,38))
[(0, 10, 30), (1, 11, 31), (2, None, 32), (3, None, 33), (4, None, 34), (None, None, 35), (None, None, 36), (None, None, 37)]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8842 次 |
| 最近记录: |