试图了解lambda

时间:2011-06-15 04:47:45

标签: python

当我这样做时

dict = {'Alice': '7898', 'Beth': '9102', 'Cecil': '3258'}
print filter(lambda x: x, dict['Alice'])

显示:7898

当我做下一个

dict = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}
print filter(lambda x: x=="2341", dict['Alice'])

它显示:

为什么它没有显示True。如何获得真实?

6 个答案:

答案 0 :(得分:5)

filter()执行以下操作:给定一个函数和一个iterable(如列表,元组等),将列表中的每个项目传递给一个函数。对于每个项目,该函数返回布尔值true或false。如果函数在项目上返回true,则该项目将添加到新列表中。

过滤完成后,将返回包含所有选定项目的新列表。这允许您根据条件“过滤”列表,并仅选择符合条件的项目。

这里发生了一件棘手的事情。 filter()循环遍历任何可迭代的。这包括一个字符串。当你传递dict ['Alice']作为迭代对象时,它传递'2341',并在字符串中的每个字符上运行过滤器。你可以按如下方式打破过滤器的逻辑:

def matches(x):
    return x == '2341'

result = ''
for char in x:
    if matches(char):
         result += char

print result

这不起作用,因为你的个人角色都不等于'2341'。

答案 1 :(得分:4)

对我而言,您的误解似乎与filter有关。您将谓词函数和可迭代对象传递给filter。它创建一个新对象,其中包含来自第一个可迭代的那些项,谓词返回一个真值(不一定是True本身,只是测试为true的东西)。两种情况下的可迭代是字符串'2341',这意味着测试了单个字母。当然,字符串'2341'不等于'2'3''4''1'中的任何一个。

尝试使用元组,更容易看到发生了什么:

>>> tup = tuple(dict['Alice'])
>>> tup
('7', '8', '9', '8')
>>> filter(lambda x: x, tup)
('7', '8', '9', '8')
>>> tup
('7', '8', '9', '8')
>>> filter(lambda x: x, tup)
('7', '8', '9', '8')
>>> filter(lambda x: x=="2341", tup)
()

答案 2 :(得分:3)

您想测试'Alice'的条目是否为'2341'。你可以通过

这样做
print dict['Alice'] == '2341'

您面临的问题不是使用lambda表单,而是使用方法filter,这在此用例中是不合适的。

一般来说,lambda表单或多或少只是一个匿名函数(参见例如here)。

答案 3 :(得分:1)

也许你想要做的是:

>>> dic = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}
>>> [i for i in dic if dic[i] == '2341']
['Alice']

如果您添加其他具有相同值的元素,您将在列表中获得所有元素

答案 4 :(得分:0)

如果你只是想调用lambda函数,你只需要像函数一样使用它:

print (lambda x: x=="2341")(dict["Alice"])

这给出了预期的结果(true)。

当您使用filter时,它将其第二个参数视为列表,因此“2341”被视为字符列表['2', '3', '4', '1'],其中没有一个等于“2341”。

我刚刚发现有趣的事情:Python 3从filter()函数返回过滤器对象,因此正确使用过滤器

print( list( filter( lambda x: x, dict['Alice'] ) ) )

返回['2', '3', '4', '1'],这可以避免最初的混淆。

答案 5 :(得分:0)

通常,可以将filter应用于两个参数:

  1. 一个功能
  2. 列表(或其他可迭代对象)
  3. filter将函数应用于列表中的每个对象,并返回函数返回的所有对象的列表True

    在你的第二个例子中,你的第一个参数是一个函数,正如预期的那样。但是你的第二个参数不是一个列表 - 它是一个字符串“2341”(在字典中查找“Alice”的结果)。

    编辑:我最初得到了下一部分错误。感谢其他海报让它正确。)过滤器将字符串视为列表,将函数应用于每个字符并仅保留这些字符它返回True(没有一个),导致一个空字符串。现在,如果你回顾一下你的第一个例子,那就有同样的问题,只有(不好?)运气,答案是你所期望的。

    正如另一张海报建议的那样,也许你想更直接地应用你的功能。在第一个例子中:

    (lambda x: x)(dict['Alice'])
    

    在第二个例子中:

    (lambda x: x=="2341")(dict['Alice'])