Python 涉及 map 和 reduce 的怪事
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
上的最终 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
这是一个非常好的功能。函数式编程并不意味着 "use map and reduce everywhere possible".
所以,这里有一些很好的函数式编程:
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])
抱歉标题模糊,但我真的不知道这里发生了什么。
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
这是一个非常好的功能。函数式编程并不意味着 "use map and reduce everywhere possible".
所以,这里有一些很好的函数式编程:
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])