涉及 map 和 reduce 的 Python 怪异

标签 python arrays python-3.x functional-programming off-by-one

抱歉标题含糊不清,但我真的不知道这里发生了什么。

from functools import reduce

arr = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

def strxo(n):
    if (n == -1):
        return "X"
    elif (n == 1):
        return "O"
    else:
        return "_"

def prboard(board):
    print(reduce(lambda x, y: x + "\n" + y, list(map(lambda l: reduce(lambda a, b: strxo(a) + strxo(b), l), board))))

prboard(arr)

期望的输出:

___
___
___

实际输出:

__
__
__

当我将 strxo 上的最终 else 更改为 return str(n) 而不是 return "_" 我得到:

000
000
000

这是我所期望的和我想要的形状,但我想替换那些零。这是什么原因造成的?

最佳答案

问题是你最内部的 reduce 函数,作用于你的子列表的函数,总是将第二个参数转换为 _:

lambda a, b: strxo(a) + strxo(b)

因此,在 reduce 的最后一个元素上,b__,它变成了 _!

您想首先将 map strxo 到所有内容上,然后使用连接减少。

所以你想要这样的东西:

reduce(lambda x, y: x + "\n" + y, map(lambda l: reduce(lambda a, b: a + b, map(strxo, l)), board))

请注意,我删除了对 list 的不必要调用。

但更重要的是,停止使用 reduce 和串联运算符来连接字符串!

它不必要地冗长,而且启动效率低下(它将具有二次时间复杂度)。

相反,使用:

joinstr = ''.join

这是一个非常好的函数。函数式编程并不意味着“尽可能使用 map 和 reduce”。

所以,这里有一些很好的函数式编程:

joinstr = ''.join
join_newline = '\n'.join

def board_str(board):
    return join_newline(map(lambda l: joinstr(map(strxo,l)), board))

更好的是,您应该只使用列表理解,它们是显着的函数构造(Python 从 Haskell 那里偷走了它们,顺便说一句)。它通常比 map + lambda 更具可读性:

def board_string(board):
    return join_newline([joinstr(map(strxo, l)) for l in board])

关于涉及 map 和 reduce 的 Python 怪异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51776572/

相关文章:

javascript - 如何展平包含数组的对象数组?

python - 将嵌套的字典项合并到一个字符串中

python - 为什么django不能同时加载多个页面?

python - 当前 URL 与其中任何一个都不匹配

python - 二维数组中元素的顺序测试?

java - 如何在没有任何重复/重复字符串的情况下随机化数组?

python - 离线pip安装

python - Seaborn jointplot 联合密度水平/色标调整

python-3.x - datetime strftime %s 在 Windows 上崩溃

python-3.x - vim - 为 python3 支持配置但仍然在版本信息中显示 -python3