【问题标题】:map doesn't work as expected in python 3地图在 python 3 中不能按预期工作
【发布时间】:2014-02-04 08:26:32
【问题描述】:

这里是新手。

此代码在 python 2.7 中有效,但在 3.3 中无效

def extractFromZipFiles(zipFiles, files, toPath):
    extractFunction = lambda fileName:zipFiles.extract(fileName, toPath) 
    map (extractFunction,files)
    return

没有错误,但文件未解压缩。但是,当我用 for 循环替换时,效果很好。

def extractFromZipFiles(zipFiles, files, toPath):
    for fn in files:
        zipFiles.extract(fn, toPath)
#     extractFunction = lambda fileName:zipFiles.extract(fileName, toPath) 
#     map (extractFunction,files)
    return

代码不会出错。

【问题讨论】:

  • 因为它只是一个生成器
  • 老实说,只需使用for 循环。这方式对路人来说更明确,你到底在做什么。
  • 在 Python2 中,该 map 调用正在创建一个 Nones 列表,这是毫无意义的,不鼓励使用。 for 循环更干净。我不知道为什么人们很难写出两行好的代码,而一个蹩脚的代码就行了。
  • @gnibbler,有一个相当广泛的误解,即“pythonic”的意思是“非常短的单线”。虽然它们可以经常重叠,但在这种情况下很明显它们并不总是
  • @mhlester,是的,向他人传授这个(和其他好习惯)是此类网站的一项重要功能。

标签: python functional-programming


【解决方案1】:

通常不鼓励使用 map 来调用函数,但话虽如此,它不起作用的原因是因为 Python 3 返回一个生成器,而不是一个列表,所以在你迭代之前不会调用该函数在上面。确保它调用函数:

list(map(extractFunction,files))

但它正在创建一个未使用的列表。更好的方法是更明确:

for file in files:
    extractFunction(file)

就像正面一样,两条线确实比一条线好。

【讨论】:

    【解决方案2】:

    map 在 python3 中是一个迭代器,而在 python2 中,它计算一个列表。所以,你要找的是a way to consume the entire iterator。谢天谢地,这里有an itertools recipe:

    import collections
    def extractFromZipFiles(zipFiles, files, toPath):
        extractFunction = lambda fileName:zipFiles.extract(fileName, toPath) 
        collections.deque(map(extractFunction,files), maxlen=0)
        return
    

    【讨论】:

    • 我同意@mhlester。诚然,您的答案是正确的,但这种方法实在是太糟糕了。
    • 我只是想用最少的编辑来解决 OP 的问题。再说一次,当我看到隧道视野时,我/我/疯狂地写了一些非常不可读的代码
    • 它是一个有趣的方法。我不得不回去重新阅读这个问题,以确保这不是你的作业混淆答案之一
    • @mhlester:如果你必须考虑一下,这不是作业混淆。我试图让这些应用程序过于明显
    • 使用map 或列表推导等来处理副作用是不好的做法。这只是将糟糕的代码隐藏在另一层复杂性之下。
    猜你喜欢
    • 2021-02-26
    • 2013-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    • 2014-10-10
    • 1970-01-01
    相关资源
    最近更新 更多