【问题标题】:Handling map function in python2 & python3在python2和python3中处理map函数
【发布时间】:2017-04-26 16:43:09
【问题描述】:

最近我遇到了一个问题并且对可能的解决方案感到困惑, 代码部分是

// code part in result reader
result = map(int, input())
// consumer call
result_consumer(result)

这与它们如何工作无关,问题是当您在python2 中运行时,它会在结果获取部分引发异常,因此结果读取器可以处理异常,但如果python3 @987654324 @ 被返回,所以只有消费者才能处理异常。 是否有任何解决方案保持map 功能并处理python2python3 中的异常

python3

>>> d = map(int, input())
1,2,3,a
>>> d
<map object at 0x7f70b11ee518>
>>> 

python2

>>> d = map(int, input())
1,2,3,'a'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'a'
>>> 

【问题讨论】:

  • 除了 map 之外,还有一个完全不同的错误,即 input 在 Python 3 上无法以这种方式工作。

标签: python-2.7 python-3.x python-internals


【解决方案1】:

map 的行为并不是 python2 和 python3 之间的唯一区别,input 也是区别,您需要牢记两者之间的基本区别才能使代码兼容两者

python 3 vs python 2
  map    =   itertools.imap
  zip    =   itertools.izip
  filter =   itertools.ifilter
  range  =   xrange
  input  =   raw_input

所以要为两者编写代码,您可以使用列表解析等替代方法,它们对两者都有效,对于那些没有简单替代方法的替代方法,您可以创建新函数和/或使用条件重命名,例如

my_input = input
try: 
    raw_input
except NameError: #we are in python 3
    my_input = lambda msj=None: eval(input(msj))

(或者用你最喜欢的方式来检查正在执行的python版本)

# code part in result reader
result = [ int(x) for x in my_input() ]
# consumer call
result_consumer(result)

这样,无论您运行哪个版本的 python,您的代码都会执行相同的操作。

但正如 jsbueno 提到的,eval 和 python2 的 inputdangerous,所以使用更安全的 raw_input 或 python3 的 input

try: 
    input = raw_input
except NameError: #we are in python 3
    pass

(或者用你最喜欢的方式来检查正在执行的python版本)

那么如果您的计划是以1,2,3 的形式提供您的输入,请添加适当的拆分

# code part in result reader
result = [ int(x) for x in input().split(",") ]
# consumer call
result_consumer(result)

【讨论】:

  • 请 - 反过来,用 Python3 工作输入覆盖 Python 的 2 个损坏的输入。您的 try-except 只是重新创建了 Python3 中不存在的损坏行为。
  • @jsbueno 你是什么意思?将 my_input 更改为 raw_input??我这样做是因为它看起来像 OP 使用 py2 作为它的主要版本,我尝试使两个版本的行为相同
  • "try: raw_input else: input=raw_input` - 这使得 Python3 的良好输入版本取代了不安全和奇怪的 Python2 输入。
  • @jsbueno 我将其添加到我的答案中
【解决方案2】:

如果您总是需要在同一个地方发生异常,您总是可以通过将映射对象包装在 list 调用中来强制映射对象产生其结果:

result = list(map(int, input()))

如果在 Python 2 中发生错误,它将在调用 map 期间出现,而在 Python 3 中,错误将在调用 list 期间出现。

轻微的缺点是,对于 Python 2,您将创建一个新列表。为避免这种情况,您可以选择基于 sys.version 进行分支并仅在 Python 3 中使用 list,但这对您来说可能太乏味了。

【讨论】:

  • 您提到的“dowsnside”完全不是问题-您正在执行单个函数调用-几微秒的顺序,以响应用户输入输入-soemhting以秒为单位。
【解决方案3】:

在这种情况下,我通常使用我自己的地图版本来避免可能发生的任何问题,这是

def my_map(func,some_list):
    done = []
    for item in some_list:
        done.append( func(item) )
    return done

还有我自己的输入版本

def getinput(text):
    import sys
    ver = sys.version[0]
    if ver=="3":
        return input(text)
    else:
        return raw_input(text)

如果您正在处理一个大型项目,请将它们添加到 python 文件中,并在需要时随时导入它们,就像我所做的那样。

【讨论】:

    猜你喜欢
    • 2020-09-30
    • 1970-01-01
    • 2017-06-20
    • 1970-01-01
    • 2019-06-06
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 2015-10-24
    相关资源
    最近更新 更多