Frage Wie finde ich die Länge eines "Filter" -Objekts in Python?


>>> n = [1,2,3,4]

>>> filter(lambda x:x>3,n)
<filter object at 0x0000000002FDBBA8>

>>> len(filter(lambda x:x>3,n))
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    len(filter(lambda x:x>3,n))
TypeError: object of type 'filter' has no len()

Ich konnte nicht die Länge der Liste bekommen, die ich bekam. Also habe ich versucht, es auf eine Variable zu speichern, so ...

>>> l = filter(lambda x:x>3,n)
>>> len(l)
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    len(l)
TypeError: object of type 'filter' has no len()

Anstatt eine Schleife zu verwenden, gibt es eine Möglichkeit, die Länge davon zu bekommen?


23
2017-10-04 13:15


Ursprung


Antworten:


Sie müssen irgendwie durch das Filterobjekt iterieren. Eine Möglichkeit besteht darin, sie in eine Liste zu konvertieren:

l = list(filter(lambda x: x > 3, n))

len(l)  # <--

Aber das könnte die Verwendung besiegen filter() an erster Stelle, da Sie dies mit einem Listenverständnis leichter machen könnten:

l = [x for x in n if x > 3]

Nochmal, len(l) Gibt die Länge zurück.


42
2017-10-04 13:18



Das ist eine alte Frage, aber ich denke, diese Frage braucht eine Antwort mit dem Karte verkleinern Ideologie. Also hier:

from functools import reduce

def ilen(iterable):
    return reduce(lambda sum, element: sum + 1, iterable, 0)

ilen(filter(lambda x: x > 3, n))

Dies ist besonders gut, wenn n passt nicht in den Computerspeicher.


16
2018-06-04 07:14



Das Dokumente für Python 3 sagen, dass es einen Iterator zurückgibt

"Konstruiere einen Iterator aus diesen iterierbaren Elementen für den   Funktion gibt True zurück. "

In Python 2 gab es eine Liste zurück: see Hier. Sie müssen das Filterobjekt durchlaufen, um seine Länge zu finden.


9
2017-10-04 13:23



Allgemein, filter und reduce sind nicht pythonisch.

@arshajii hat diese Lösung getroffen:

len([x for x in n if x > 3])

Das ist ziemlich einfach, beschreibt aber nicht, was Sie genau machen wollen, und erstellt eine Liste, die zusätzlichen Speicher benötigt. Eine bessere Lösung ist die Verwendung sum mit Generator:

sum(1 for x in n if x > 3)

(Sehen Sie mehr über Generator hier: https://www.python.org/dev/peps/pep-0289/#rationale)

Jedoch, sum mit Generator ist in den meisten Fällen tatsächlich langsamer wegen der Implementierung (getestet in CPython 3.6.4):

In [1]: %timeit len([1 for x in range(10000000)])
356 ms ± 17.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [2]: %timeit sum(1 for x in range(10000000))
676 ms ± 7.05 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

1
2018-06-14 08:16



Beim Konvertieren eines Filters in eine Liste wird zusätzlicher Speicher benötigt, der für große Datenmengen möglicherweise nicht akzeptabel ist. Sie können die Länge des Filterobjekts finden, ohne es in eine Liste zu konvertieren:

sum(1 for _ in filter(lambda x: x > 3, n))


0
2017-07-14 06:41