web-dev-qa-db-fra.com

Pourquoi foo = filter (...) renvoie-t-il un <objet filtre>, pas une liste?

Travailler dans Python IDLE 3.5.0 Shell. De ma compréhension de la fonction "filtre" intégrée, il retourne une liste, un tuple ou une chaîne, selon ce que vous y entrez. Alors, pourquoi la première affectation ci-dessous fonctionne-t-elle, mais pas la deuxième (les '>>>' ne sont que les interactions interactives Python)

>>> def greetings():
    return "hello"

>>> hesaid = greetings()
>>> print(hesaid)
hello
>>> 
>>> shesaid = filter(greetings(), ["hello", "goodbye"])
>>> print(shesaid)
<filter object at 0x02B8E410>
46
Margarita

Jetez un coup d’œil à la documentation python pour filter(function, iterable)]) (de ici ):

Construisez un itérateur à partir des éléments de itérables pour lesquels la fonction renvoie la valeur true.

Donc, vous devez utiliser la liste suivante:

shesaid = list(filter(greetings(), ["hello", "goodbye"]))

Mais ce n'est probablement pas ce que vous vouliez, car il essaie d'appeler le résultat de greetings(), qui est "hello", sur les valeurs de votre liste d'entrées, et cela ne fonctionnera pas. Ici aussi, le type d'itérateur entre en jeu, car les résultats ne sont générés que lorsque vous les utilisez (par exemple, en appelant list() dessus). Donc au début, vous n'obtiendrez pas d'erreur, mais si vous essayez de faire quelque chose avec shesaid, il ne fonctionnera plus:

>>> print(list(shesaid))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable

Si vous voulez vérifier quels éléments de votre liste sont égaux à "hello", vous devez utiliser quelque chose comme ceci:

shesaid = list(filter(lambda x: x == "hello", ["hello", "goodbye"]))

(Je mets votre fonction dans un lambda, voir la réponse de Randy C pour une fonction "normale")

58
TobiMarg

filter s'attend à obtenir une fonction et quelque chose sur lequel il peut se déplacer. La fonction doit renvoyer True ou False pour chaque élément de l'itérable. Dans votre exemple particulier, ce que vous cherchez à faire est quelque chose comme ceci:

In [47]: def greetings(x):
   ....:     return x == "hello"
   ....:

In [48]: filter(greetings, ["hello", "goodbye"])
Out[48]: ['hello']

Notez que dans Python 3, il peut être nécessaire d’utiliser list(filter(greetings, ["hello", "goodbye"])) pour obtenir le même résultat.

6
Randy

Veuillez voir cet exemple d’implémentation de filter pour comprendre comment cela fonctionne dans 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))

Voici un exemple d'utilisation de filter ou my_filter générateurs:

>>> greetings = {'hello'}
>>> spoken = my_filter(greetings.__contains__, ('hello', 'goodbye'))
>>> print('\n'.join(spoken))
hello
2
Noctis Skytower

De la documentation

Notez que filter(function, iterable) est équivalent à [item for item in iterable if function(item)]

En python3, plutôt que de retourner une liste; filtrer, la carte retourne un itérable. Votre tentative devrait fonctionner sur python2 mais pas sur python3

Clairement, vous obtenez un objet filtre, faites-en une liste.

shesaid = list(filter(greetings(), ["hello", "goodbye"]))
1
Ahsanul Haque

la raison pour laquelle il renvoie < filter object > est que, le filtre est une classe au lieu d'une fonction intégrée.

help(filter) vous obtiendrez les éléments suivants: Aide sur le filtre de classe dans les modules intégrés:

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.
0
JordanChina