簡體   English   中英

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上更改final elsereturn str(n)而不是return "_"我得到:

000
000
000

這是我期望的以及我想要的形狀,但是我想替換那些零。 是什么原因造成的?

問題在於,最內部的reduce函數(作用在子列表上的那個函數)總是將第二個參數轉換為_

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

因此,在該reduce的最后一個元素上, b__ ,它變成_

strxostrxo 映射到所有內容, 然后再減少使用串聯。

所以你想要這樣的東西:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM