2017-06-07 4 views
3

Ich lerne, wie man die filter Funktion verwendet.Python: Filterobjekt wird von selbst leer

Dies ist der Code, den ich geschrieben habe:

people = [{'name': 'Mary', 'height': 160}, 
      {'name': 'Isla', 'height': 80}, 
      {'name': 'Sam'}] 

people2 = filter(lambda x: "height" in x, people) 

Wie Sie sehen können, was ich versuche alle Wörterbücher zu tun ist, zu entfernen, die die 'height' Schlüssel nicht enthalten.

Der Code richtig, in der Tat funktioniert, wenn ich tun:

print(list(people2)) 

ich:

[{'name': 'Mary', 'height': 160}, {'name': 'Isla', 'height': 80}] 

Das Problem ist, dass wenn ich es zweimal:

print(list(people2)) 
print(list(people2)) 

die Beim zweiten Mal bekomme ich eine leere Liste.

Können Sie mir erklären warum?

+0

Verwandte: https://stackoverflow.com/questions/21715268/list-returned-by-map-function-disappears-after-one-use, https://stackoverflow.com/questions/40960036/cannot-use-list-more-than-once-on-a-map-object –

Antwort

6

Dies ist ein klassisches python3 doh !.

Ein Filter ist ein spezielles iterierbares Objekt, über das Sie iterieren können. Ähnlich wie bei einem Generator können Sie jedoch nur einmal darüber iterieren. Wenn Sie also list(people2) aufrufen, durchlaufen Sie jedes Element des Objekts filter, um die list zu generieren. An diesem Punkt haben Sie das Ende des iterablen Bereichs erreicht und können nicht mehr zurückkehren.

Also, wenn Sie wieder list(people2) aufrufen, erhalten Sie eine leere Liste.

Demo:

>>> l = range(10) 
>>> k = filter(lambda x: x > 5, l) 
>>> list(k) 
[6, 7, 8, 9] 
>>> list(k) 
[] 

Ich sollte mit python2 erwähnen, dass, filter eine Liste, so dass Sie nicht in dieses Problem laufen. Das Problem tritt auf, wenn Sie die faule Auswertung von py3 ins Bild bringen.

+0

oh, ok, also wenn ich es mehr als einmal verwenden möchte, muss ich es nur speichern auf eine andere Variable, wie * people3 = list (people2) *, oder? –

+0

@ L'ultimo Ja, du hast es. –

+0

Ok, wirklich danke! :) –

1

Es ist, weil, was Filter wirklich dreht, ist ein Iterator. Dieser Iterator macht erst dann wirklich etwas, wenn Sie beginnen, seine Ergebnisse zu verwenden, in diesem Fall, wenn Sie ihn in eine Liste umwandeln. people2 ist das Ding, das bereit ist, die Liste von Leuten zu filtern, dann, wenn Liste angerufen wird, iteriert es durch die Liste von Leuten und liefert das gefilterte Resultat. Jetzt, da der Iterator fertig ist, bleibt nichts mehr übrig, um darüber zu iterieren. Wenn Sie die Liste also ein zweites Mal aufrufen, ist nichts da.

Lesen Sie dies für einige weitere Details - Lazy evaluation python