So verwenden Sie Filter, Karte und reduzieren in Python 3

filter , map und reduce Arbeit perfekt in Python 2. Hier ist ein Beispiel:

 >>> def f(x): return x % 2 != 0 and x % 3 != 0 >>> filter(f, range(2, 25)) [5, 7, 11, 13, 17, 19, 23] >>> def cube(x): return x*x*x >>> map(cube, range(1, 11)) [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000] >>> def add(x,y): return x+y >>> reduce(add, range(1, 11)) 55 

Aber in Python 3 bekomme ich folgende Ausgänge:

 >>> filter(f, range(2, 25)) <filter object at 0x0000000002C14908> >>> map(cube, range(1, 11)) <map object at 0x0000000002C82B70> >>> reduce(add, range(1, 11)) Traceback (most recent call last): File "<pyshell#8>", line 1, in <module> reduce(add, range(1, 11)) NameError: name 'reduce' is not defined 

Ich würde mich freuen, wenn mir jemand erklären könnte, warum das so ist.

Screenshot von Code für weitere Klarheit:

IDLE-Sessions von Python 2 und 3 Seite an Seite

  • Wie kann man zwei Listen von unebener Länge in Python elegant verknüpfen?
  • Überprüfen Sie den Rückgabecode eines Befehls, wenn der Unterprozess eine CalledProcessError-Ausnahme auslöst
  • Kann nicht zbar installieren
  • Was ist der Zweck von collections.ChainMap?
  • Namespace vs regelmäßiges Paket
  • Python - finden Muster in einer Handlung
  • Import Python-Modul fehlschlägt (http.cookies)
  • Verhalten des Deskriptorkonzepts in Python (verwirrend)
  • 3 Solutions collect form web for “So verwenden Sie Filter, Karte und reduzieren in Python 3”

    Sie können über die Änderungen in Was ist neu in Python 3.0 lesen. Sie sollten es gründlich lesen, wenn Sie von 2.x auf 3.x verschieben, da viel geändert wurde.

    Die ganze Antwort hier sind Zitate aus der Dokumentation.

    Ansichten und Iteratoren anstelle von Listen

    Einige bekannte APIs geben keine Listen mehr zurück:

    • […]
    • map() und filter() return iteratoren. Wenn du wirklich eine Liste brauchst, ist eine schnelle Korrektur zB eine list(map(...)) , aber eine bessere Korrektur ist oft ein Listenverständnis zu verwenden (besonders wenn der ursprüngliche Code Lambda verwendet) oder den Code umschreiben, so dass es doesn Ich brauche überhaupt eine Liste. Besonders schwierig ist die map() für die Nebenwirkungen der Funktion aufgerufen; Die korrekte Transformation ist eine regelmäßige Schleife verwenden (da die Erstellung einer Liste wäre nur verschwenderisch).
    • […]

    Builtins

    • […]
    • Entfernt reduce() . Verwenden Sie functools.reduce() wenn Sie es wirklich brauchen; Allerdings sind 99 Prozent der Zeit eine explizite for Schleife besser lesbar.
    • […]

    Die Funktionalität von map und filter wurde absichtlich geändert, um Iteratoren zurückzugeben, und reduzierte wurde von einem eingebauten und in functools.reduce .

    Also, für filter und map , können Sie wrap sie mit list() , um die Ergebnisse wie Sie zuvor gesehen zu sehen.

     >>> def f(x): return x % 2 != 0 and x % 3 != 0 ... >>> list(filter(f, range(2, 25))) [5, 7, 11, 13, 17, 19, 23] >>> def cube(x): return x*x*x ... >>> list(map(cube, range(1, 11))) [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000] >>> import functools >>> def add(x,y): return x+y ... >>> functools.reduce(add, range(1, 11)) 55 >>> 

    Die Empfehlung ist jetzt, dass Sie Ihre Nutzung von Karte ersetzen und Filter mit Generatoren Ausdrücke oder Liste Verständnisse. Beispiel:

     >>> def f(x): return x % 2 != 0 and x % 3 != 0 ... >>> [i for i in range(2, 25) if f(i)] [5, 7, 11, 13, 17, 19, 23] >>> def cube(x): return x*x*x ... >>> [cube(i) for i in range(1, 11)] [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000] >>> 

    Sie sagen, dass für Loops sind 99 Prozent der Zeit leichter zu lesen als zu reduzieren, aber ich würde nur mit functools.reduce .

    Edit : Die 99-Prozent-Figur wird direkt von der What's New In Python 3.0 Seite von Guido van Rossum verfasst.

    Als Addendum zu den anderen Antworten klingt das wie ein guter Gebrauchsfall für einen Kontextmanager, der die Namen dieser Funktionen auf diejenigen umbenimmt, die eine Liste zurückgeben und im globalen Namespace reduce .

    Eine schnelle Implementierung könnte so aussehen:

     from contextlib import contextmanager @contextmanager def noiters(*funcs): if not funcs: funcs = [map, filter, zip] # etc from functools import reduce globals()[reduce.__name__] = reduce for func in funcs: globals()[func.__name__] = lambda *ar, func = func, **kwar: list(func(*ar, **kwar)) try: yield finally: del globals()[reduce.__name__] for func in funcs: globals()[func.__name__] = func 

    Mit einer Verwendung, die so aussieht:

     with noiters(map): from operator import add print(reduce(add, range(1, 20))) print(map(int, ['1', '2'])) 

    Welche Drucke:

     190 [1, 2] 

    Nur meine 2 Cent 🙂

    Python ist die beste Programmiersprache der Welt.