为啥 foo = filter(...) 返回一个 <filter object>,而不是一个列表? [复制]
Posted
技术标签:
【中文标题】为啥 foo = filter(...) 返回一个 <filter object>,而不是一个列表? [复制]【英文标题】:Why does foo = filter(...) return a <filter object>, not a list? [duplicate]为什么 foo = filter(...) 返回一个 <filter object>,而不是一个列表? [复制] 【发布时间】:2016-01-15 10:20:15 【问题描述】:在 Python IDLE 3.5.0 shell 中工作。根据我对内置“过滤器”函数的理解,它返回列表、元组或字符串,具体取决于您传递给它的内容。那么,为什么下面的第一个分配有效,而第二个无效('>>> 只是交互式 Python 提示)
>>> def greetings():
return "hello"
>>> hesaid = greetings()
>>> print(hesaid)
hello
>>>
>>> shesaid = filter(greetings(), ["hello", "goodbye"])
>>> print(shesaid)
<filter object at 0x02B8E410>
【问题讨论】:
在我的机器上,help(filter)
说它返回一个迭代器,而不是列表、元组或字符串。您可能正在查看旧版本 Python 的文档。在任何情况下,您的filter
表达式即使在旧版本中也不起作用,因为filter
的第一个参数必须是可调用的,而greetings()
返回的值不是可调用的。
我使用的是一个旧教程,它没有说明 Python 的版本。谢谢凯文....虽然我不明白(只是从这里开始:-)...你的意思是:“因为 filter 的第一个参数必须是可调用的,并且 greetings() 返回的值不是一个可调用的。”
接下来你让我自学什么是可调用对象。在论坛和其他地方都找到了一些主题。再次感谢! (试图编辑以前的评论,但 *** 不允许...
“不允许”?这当然是允许的——你能够存储返回值(没有引发异常);该值不是您所期望的。这里的原标题有些误导。
【参考方案1】:
filter 期望得到一个函数和它可以迭代的东西。该函数应为迭代中的每个元素返回 True 或 False。在您的特定示例中,您要执行的操作类似于以下内容:
In [47]: def greetings(x):
....: return x == "hello"
....:
In [48]: filter(greetings, ["hello", "goodbye"])
Out[48]: ['hello']
请注意,在 Python 3 中,可能需要使用 list(filter(greetings, ["hello", "goodbye"]))
才能获得相同的结果。
【讨论】:
【参考方案2】:来自文档
注意
filter(function, iterable)
等价于[item for item in iterable if function(item)]
在python3中,而不是返回一个列表;过滤器,映射返回一个可迭代的。您的尝试应该适用于 python2,但不适用于 python3
很明显,你得到了一个过滤器对象,把它变成一个列表。
shesaid = list(filter(greetings(), ["hello", "goodbye"]))
【讨论】:
【参考方案3】:请查看filter
的示例实现以了解它在 Python 3 中的工作原理:
def my_filter(function, iterable):
"""my_filter(function or None, iterable) --> filter object
Return an iterator yielding those items of iterable for which function(item)
is true. If function is None, return the items that are true."""
if function is None:
return (item for item in iterable if item)
return (item for item in iterable if function(item))
以下是如何使用filter
或my_filter
生成器的示例:
>>> greetings = 'hello'
>>> spoken = my_filter(greetings.__contains__, ('hello', 'goodbye'))
>>> print('\n'.join(spoken))
hello
【讨论】:
【参考方案4】:查看filter(function, iterable)
的python 文档(来自here):
从 iterable 中 function 返回 true 的那些元素构造一个迭代器。
所以为了得到一个列表,你必须使用列表类:
shesaid = list(filter(greetings(), ["hello", "goodbye"]))
但这可能不是您想要的,因为它试图在您的输入列表的值上调用greetings()
的结果,即“hello”,这将不起作用。在这里,迭代器类型也发挥了作用,因为在您使用它们之前不会生成结果(例如通过在其上调用list()
)。所以一开始你不会收到错误,但是当你尝试使用shesaid
做某事时,它会停止工作:
>>> print(list(shesaid))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
如果您想检查列表中的哪些元素等于“hello”,您必须使用以下内容:
shesaid = list(filter(lambda x: x == "hello", ["hello", "goodbye"]))
(我将您的函数放入 lambda,请参阅 Randy C 对“正常”函数的回答)
【讨论】:
请注意,由于()
,第一行shesaid
不会在输入列表的值上调用greetings
——它会尝试调用greetings()
返回的值。所以它会尝试调用"hello"
(字符串),就好像它是一个函数一样。
感谢 DSM,-是的,您的评论证实了 TobiMarg 的回复让我对正在发生的事情的确切理解。清除...一旦得到它! :-)
@DSM 谢谢!那是一个重要的错误。我现在修好了。【参考方案5】:
它返回< filter object >
的原因是,filter是类而不是内置函数。
help(filter)
你会得到以下信息:
关于内置模块中的类过滤器的帮助:
class filter(object)
| filter(function or None, iterable) --> filter object
|
| Return an iterator yielding those items of iterable for which function(item)
| is true. If function is None, return the items that are true.
|
| Methods defined here:
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __iter__(self, /)
| Implement iter(self).
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
|
| __next__(self, /)
| Implement next(self).
|
| __reduce__(...)
| Return state information for pickling.
【讨论】:
以上是关于为啥 foo = filter(...) 返回一个 <filter object>,而不是一个列表? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Scheme `filter` 表单不能“按顺序”处理列表元素?
为啥代理下的getContextPath()返回的是HttpServlet内部的内部路径,而不是Filter内部的路径?