首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python3与Python2映射行为

Python3与Python2映射行为
EN

Stack Overflow用户
提问于 2012-08-18 03:13:10
回答 3查看 10K关注 0票数 20

在Python2中,一个常见的(旧的,遗留的)成语是使用map加入长度不均匀的迭代器,使用如下形式的map(None,iter,iter,...)

代码语言:javascript
运行
复制
>>> map(None,xrange(5),xrange(10,12))
[(0, 10), (1, 11), (2, None), (3, None), (4, None)]

在Python2中,它被扩展为最长的迭代器是返回列表的长度,如果其中一个比另一个短,则填充None

在Python 3中,这是不同的。首先,不能将None用作位置1中可调用的参数:

代码语言:javascript
运行
复制
>>> 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

好吧--我可以这样解决:

代码语言:javascript
运行
复制
>>> def f(*x): return x    
... 
>>> list(map(f, *(range(5),range(10,12))))
[(0, 10), (1, 11)]

但是现在,我有一个不同的问题:map返回最短的迭代器的长度--不再用None填充。

当我将Python 2代码移植到Python 3时,这并不是一个非常罕见的成语,而且我还没有想出一个简单的解决方案。

不幸的是,2to3工具不会发现了这一点

代码语言:javascript
运行
复制
-map(None,xrange(5),xrange(10,18))
+list(map(None,list(range(5)),list(range(10,18)))) 

有什么建议吗?

编辑

有一些关于这个成语有多普遍的讨论。看这个,所以张贴

我正在更新我还在高中时写的遗留代码。看看由Raymond编写的2003年Python教程是书面和讨论,并指出了这个特定的映射行为。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-08-18 07:01:54

这次我自己回答问题。

使用Python3x,您可以像这样使用最长

代码语言:javascript
运行
复制
>>> 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)]

你也可以自己滚吧,我想:

代码语言:javascript
运行
复制
>>> 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)]
票数 2
EN

Stack Overflow用户

发布于 2012-08-18 03:17:58

itertools.zip_longest做你想做的事,用一个更容易理解的名字。:)

票数 19
EN

Stack Overflow用户

发布于 2020-05-12 20:30:51

一种方法是,如果您需要Python 2中的一些过时的功能,那么一种方法就是自己编写它。当然,它不是内置的功能,但至少它是一些东西。

下面的代码片段包含27行

代码语言:javascript
运行
复制
#!/usr/bin/env python3

def fetch(sequence, index):
  return None if len(sequence) <= index else sequence[index]

def mymap(f, *args):
  max_len = 0
  for i in range(len(args)): 
      max_len = max(max_len, len(args[i]))
  out = []
  for i in range(max_len):
      t = []
      for j in range(len(args)): 
          t.append(fetch(args[j],i))      

      if f != None:
          # Use * for unpack arguments from Arbitarily argument list
          # Use ** for unpack arguments from Keyword argument list
          out.append(f(*t))
      else:
          out.append(tuple(t))
  return out 

if __name__ == '__main__':
    print(mymap(None, [1,2,3,4,5],[2,1,3,4],[3,4]))
    print(mymap(None,range(5),range(10,12)))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12015521

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档