[英]Python weirdness involving map and reduce
抱歉,标题模糊,但我真的不知道这是怎么回事。
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
上更改final else
以return str(n)
而不是return "_"
我得到:
000
000
000
这是我期望的以及我想要的形状,但是我想替换那些零。 是什么原因造成的?
问题在于,最内部的reduce函数(作用在子列表上的那个函数)总是将第二个参数转换为_
:
lambda a, b: strxo(a) + strxo(b)
因此,在该reduce的最后一个元素上, b
是__
,它变成_
!
您strxo
将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
这是一个非常好的功能。 函数式编程并不意味着“使用映射并尽可能地减少”。
因此,这里有一些好的函数式编程:
joinstr = ''.join
join_newline = '\n'.join
def board_str(board):
return join_newline(map(lambda l: joinstr(map(strxo,l)), board))
更重要的是,你应该只使用列表内涵 ,这是突出地功能结构(Python从哈斯克尔偷来的,顺便说一句)。 它通常比map
+ lambda
更具可读性:
def board_string(board):
return join_newline([joinstr(map(strxo, l)) for l in board])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.