8
class FoodExpert:
    def init(self):
        self.goodFood = []
    def addGoodFood(self, food):
        self.goodFood.append(food)
    def likes(self, x):
        return x in self.goodFood
    def prefers(self, x, y):
        x_rating = self.goodFood.index(x)
        y_rating = self.goodFood.index(y)
        if x_rating > y_rating:
            return y
        else:
            return x

声明这个类后,我写了这段代码:

>>> f = FoodExpert()
>>> f.init()
>>> map(f.addGoodFood, ['SPAM', 'Eggs', 'Bacon', 'Rat', 'Spring Surprise'])
[None, None, None, None, None]

>>> f.goodFood
['SPAM', 'Eggs', 'Bacon', 'Rat', 'Spring Surprise']

我无法理解 map 函数是如何在幕后工作的,为什么它会返回一个包含所有内容的列表None,但是当我检查f.goodFood元素是否已添加到那里时?

4

5 回答 5

9

map在可迭代对象上应用一个函数并返回一个新列表,其中该函数应用于每个项目。

在您的情况下,它显示是None因为f.addGoodFood函数不返回任何内容。

出于测试目的改变addGoodFood这种方式:

def addGoodFood(self, food):
    self.goodFood.append(food)
    return "test"

看看:

>>> map(f.addGoodFood, ['SPAM', 'Eggs', 'Bacon', 'Rat', 'Spring Surprise'])
['test', 'test', 'test', 'test', 'test']
于 2013-08-22T18:33:06.453 回答
5

那是因为addGoodFood没有返回任何东西。让它返回一些东西:

def addGoodFood(self, food):
    self.goodFood.append(food)
    return food

map正在创建调用列表中每个项目的结果列表。addGoodFood而且,由于appendlist 的方法总是返回None,所以你会得到一个None's 的列表。

此外,您可能希望将init功能更改为:

def __init__(self):
    self.goodFood = []

__init__是一种处理类初始化的特殊方法。使用它意味着你不必做f.init().

于 2013-08-22T18:31:56.473 回答
4

result = map(function, iterable)相当于:

result = []
for item in iterable:
    result.append(function(item))

因此,它在内部构建了一个列表,在该列表中附加了对列表中的每个项目应用函数的结果。

由于您的函数addGoodFood不返回任何内容,因此该map函数返回一个Nones 列表。

goodFoods您的函数具有将其项目附加到列表的副作用,goodFoods列表被填充并具有所有元素。但是,正如我所说,函数不返回任何内容,因此 map 返回了一个与原始列表(因为它应用于每个元素)大小相同的列表,其中充满了Nones。

于 2013-08-22T18:31:55.863 回答
4

问题中的代码返回一个包含None元素的列表,因为addGoodFood()没有显式返回任何内容(隐式地,它会返回None)。map()收集您调用的函数的结果,并使用这些结果创建一个新列表。

您不应该使用map()不返回值的函数。在这种情况下,addGoodFood()适合使用它。这就是你应该写的方式:

for food in ['SPAM', 'Eggs', 'Bacon', 'Rat', 'Spring Surprise']:
    f.addGoodFood(food)

map()回答这个问题:引擎盖下是如何工作的?就是这样:

def map(func, lst):
    result = []
    for e in lst:
        result.append(func(e))
    return result

在上面的函数中,很明显为什么你会得到一个None元素列表:如果传递的函数返回None,那么循环将执行result.append(None),并且返回的列表将只包含None在每个位置。

于 2013-08-22T18:32:03.413 回答
3

因为你没有从addGoodFood函数中返回任何东西。

于 2013-08-22T18:33:13.740 回答