Suche…


Syntax

  • map (Funktion, iterable [, * additional_iterables])
  • future_builtins.map (Funktion, iterable [, * additional_iterables])
  • itertools.imap (Funktion, iterable [, * additional_iterables])

Parameter

Parameter Einzelheiten
Funktion Funktion für das Mapping (muss so viele Parameter wie iterierbare Werte annehmen) (nur Position )
iterable Die Funktion wird auf jedes Element des Iterierbaren angewendet (nur für Position ).
* additional_iterables sehen Sie iterable, aber beliebig viele ( optional , nur positionell )

Bemerkungen

Alles, was mit map kann, kann auch mit comprehensions :

list(map(abs, [-1,-2,-3]))    # [1, 2, 3]
[abs(i) for i in [-1,-2,-3]]  # [1, 2, 3]

Sie benötigen allerdings zip wenn Sie mehrere iterable haben:

import operator
alist = [1,2,3]
list(map(operator.add, alist, alist))  # [2, 4, 6]
[i + j for i, j in zip(alist, alist)]  # [2, 4, 6]

Listenverständnisse sind effizient und können in vielen Fällen schneller als die map Testen Sie daher die Zeiten beider Ansätze, wenn Geschwindigkeit für Sie wichtig ist.

Grundlegende Verwendung von map, itertools.imap und future_builtins.map

Die Kartenfunktion ist die einfachste unter den für die Funktionsprogrammierung verwendeten Python-Einbauten. map() wendet eine bestimmte Funktion auf jedes Element in einer iterierbaren Funktion an:

names = ['Fred', 'Wilma', 'Barney']
Python 3.x 3.0
map(len, names)  # map in Python 3.x is a class; its instances are iterable
# Out: <map object at 0x00000198B32E2CF8>

Eine Python 3-kompatible map ist im Modul future_builtins :

Python 2.x 2.6
from future_builtins import map  # contains a Python 3.x compatible map()
map(len, names)                  # see below
# Out: <itertools.imap instance at 0x3eb0a20>

Alternativ kann man in Python 2 imap von itertools , um einen Generator zu erhalten

Python 2.x 2.3
map(len, names)   # map() returns a list
# Out: [4, 5, 6]

from itertools import imap
imap(len, names)  # itertools.imap() returns a generator
# Out: <itertools.imap at 0x405ea20>

Das Ergebnis kann explizit in eine list , um die Unterschiede zwischen Python 2 und 3 zu beseitigen:

list(map(len, names))
# Out: [4, 5, 6]

map() kann durch ein äquivalentes Listenverständnis oder Generatorausdruck ersetzt werden :

[len(item) for item in names] # equivalent to Python 2.x map()
# Out: [4, 5, 6]

(len(item) for item in names) # equivalent to Python 3.x map()
# Out: <generator object <genexpr> at 0x00000195888D5FC0>

Zuordnen jedes Werts in einem iterierbaren Element

Sie können zum Beispiel den absoluten Wert jedes Elements annehmen:

list(map(abs, (1, -1, 2, -2, 3, -3))) # the call to `list` is unnecessary in 2.x
# Out: [1, 1, 2, 2, 3, 3]

Anonyme Funktion unterstützt auch das Mappen einer Liste:

map(lambda x:x*2, [1, 2, 3, 4, 5])
# Out: [2, 4, 6, 8, 10]

oder Dezimalwerte in Prozent umrechnen:

def to_percent(num):
    return num * 100

list(map(to_percent, [0.95, 0.75, 1.01, 0.1]))
# Out: [95.0, 75.0, 101.0, 10.0]

oder Dollar in Euro umrechnen (Wechselkurs):

from functools import partial
from operator import mul

rate = 0.9  # fictitious exchange rate, 1 dollar = 0.9 euros
dollars = {'under_my_bed': 1000,
           'jeans': 45,
           'bank': 5000}

sum(map(partial(mul, rate), dollars.values()))
# Out: 5440.5

functools.partial ist eine bequeme Methode, um Parameter von Funktionen so functools.partial , dass sie mit map anstatt lambda oder benutzerdefinierte Funktionen zu erstellen.

Zuordnungswerte verschiedener iterables

Berechnen Sie zum Beispiel den Durchschnitt jedes i ten Elements mehrerer iterierbarer Elemente:

def average(*args):
    return float(sum(args)) / len(args)  # cast to float - only mandatory for python 2.x

measurement1 = [100, 111, 99, 97]
measurement2 = [102, 117, 91, 102]
measurement3 = [104, 102, 95, 101]

list(map(average, measurement1, measurement2, measurement3))
# Out: [102.0, 110.0, 95.0, 100.0]

Es gibt unterschiedliche Anforderungen, wenn je nach Version von Python mehr als ein iterierbares Element an die map :

  • Die Funktion muss so viele Parameter enthalten, wie iterierbare Werte vorhanden sind:

    def median_of_three(a, b, c):
        return sorted((a, b, c))[1]
    
    list(map(median_of_three, measurement1, measurement2))
    

    TypeError: median_of_three () fehlt 1 erforderliches Positionsargument: 'c'

    list(map(median_of_three, measurement1, measurement2, measurement3, measurement3))
    

    TypeError: median_of_three () benötigt 3 Positionsargumente, aber 4 wurden angegeben

Python 2.x 2.0.1
  • map : Die Zuordnung Iterierten solange man iterable noch nicht vollständig verbraucht ist , sondern übernimmt None von dem vollständig verbraucht Iterables:

    import operator
    
    measurement1 = [100, 111, 99, 97]
    measurement2 = [102, 117]
    
    # Calculate difference between elements
    list(map(operator.sub, measurement1, measurement2))
    

    TypeError: nicht unterstützte Operandentypen für -: 'int' und 'NoneType'

  • itertools.imap und future_builtins.map : Das Mapping stoppt, sobald eine iterable stoppt:

    import operator
    from itertools import imap
    
    measurement1 = [100, 111, 99, 97]
    measurement2 = [102, 117]
    
    # Calculate difference between elements
    list(imap(operator.sub, measurement1, measurement2))
    # Out: [-2, -6]
    list(imap(operator.sub, measurement2, measurement1))
    # Out: [2, 6]
    
Python 3.x 3.0.0
  • Das Mapping stoppt, sobald eine Iteration stoppt:

    import operator
    
    measurement1 = [100, 111, 99, 97]
    measurement2 = [102, 117]
    
    # Calculate difference between elements
    list(map(operator.sub, measurement1, measurement2))
    # Out: [-2, -6]
    list(map(operator.sub, measurement2, measurement1))
    # Out: [2, 6]
    

Transponieren mit Map: Verwenden von "None" als Funktionsargument (nur Python 2.x)

from itertools import imap
from future_builtins import map as fmap # Different name to highlight differences

image = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9]]

list(map(None, *image))
# Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
list(fmap(None, *image))
# Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
list(imap(None, *image))
# Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

image2 = [[1, 2, 3],
          [4, 5],
          [7, 8, 9]]
list(map(None, *image2))
# Out: [(1, 4, 7), (2, 5, 8), (3, None, 9)]  # Fill missing values with None
list(fmap(None, *image2))
# Out: [(1, 4, 7), (2, 5, 8)]                # ignore columns with missing values
list(imap(None, *image2))
# Out: [(1, 4, 7), (2, 5, 8)]                # dito
Python 3.x 3.0.0
list(map(None, *image))

TypeError: 'NoneType'-Objekt ist nicht aufrufbar

Es gibt jedoch eine Problemumgehung, um ähnliche Ergebnisse zu erzielen:

def conv_to_list(*args):
    return list(args)

list(map(conv_to_list, *image))
# Out: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

Serien- und Parallelmapping

map () ist eine integrierte Funktion, dh sie ist überall verfügbar, ohne dass eine 'import'-Anweisung verwendet werden muss. Es ist überall wie print () verfügbar. Wenn Sie sich Beispiel 5 ansehen, werden Sie feststellen, dass ich eine Importanweisung verwenden musste, bevor ich Pretty Print (import pprint) verwenden konnte. Daher ist pprint keine eingebaute Funktion

Serienmapping

In diesem Fall wird jedes Argument des Iterers in aufsteigender Reihenfolge als Argument an die Abbildungsfunktion übergeben. Dies tritt auf, wenn wir nur eine einzige Abbildung haben, für die eine Abbildung möglich ist, und die Mapping-Funktion ein einziges Argument erfordert.

Beispiel 1

insects = ['fly', 'ant', 'beetle', 'cankerworm']
f = lambda x: x + ' is an insect'
print(list(map(f, insects))) # the function defined by f is executed on each item of the iterable insects

führt in

['fly is an insect', 'ant is an insect', 'beetle is an insect', 'cankerworm is an insect']

Beispiel 2

print(list(map(len, insects))) # the len function is executed each item in the insect list

führt in

[3, 3, 6, 10]

Parallele Abbildung

In diesem Fall wird jedes Argument der Mapping-Funktion parallel von allen iterierbaren Elementen (eines von jedem iterierbaren Element) abgerufen. Die Anzahl der gelieferten Iterables muss daher mit der Anzahl der von der Funktion benötigten Argumente übereinstimmen.

carnivores = ['lion', 'tiger', 'leopard', 'arctic fox']
herbivores = ['african buffalo', 'moose', 'okapi', 'parakeet']
omnivores = ['chicken', 'dove', 'mouse', 'pig']

def animals(w, x, y, z):
    return '{0}, {1}, {2}, and {3} ARE ALL ANIMALS'.format(w.title(), x, y, z)

Beispiel 3

# Too many arguments
# observe here that map is trying to pass one item each from each of the four iterables to len. This leads len to complain that
# it is being fed too many arguments
print(list(map(len, insects, carnivores, herbivores, omnivores)))

führt in

TypeError: len() takes exactly one argument (4 given)

Beispiel 4

# Too few arguments
# observe here that map is suppose to execute animal on individual elements of insects one-by-one. But animals complain when
# it only gets one argument, whereas it was expecting four.
print(list(map(animals, insects)))

führt in

TypeError: animals() missing 3 required positional arguments: 'x', 'y', and 'z'

Beispiel 5

# here map supplies w, x, y, z with one value from across the list
import pprint
pprint.pprint(list(map(animals, insects, carnivores, herbivores, omnivores)))

führt in

 ['Fly, lion, african buffalo, and chicken ARE ALL ANIMALS',
 'Ant, tiger, moose, and dove ARE ALL ANIMALS',
 'Beetle, leopard, okapi, and mouse ARE ALL ANIMALS',
 'Cankerworm, arctic fox, parakeet, and pig ARE ALL ANIMALS']


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow