Zoeken…


Syntaxis

  • map (functie, iterable [, * extra_iterables])
  • future_builtins.map (function, iterable [, * addition_iterables])
  • itertools.imap (functie, iterabel [, * extra_iterabelen])

parameters

Parameter Details
functie functie voor mapping (moet evenveel parameters bevatten als er iterables zijn) ( alleen positioneel )
iterable de functie wordt toegepast op elk element van de iterabele ( alleen positioneel )
* additional_iterables zie iterabel, maar zoveel als je wilt ( optioneel , alleen positioneel )

Opmerkingen

Alles wat met map kan worden gedaan, kan ook met comprehensions worden gedaan:

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

Hoewel je zip nodig hebt als je meerdere iterables hebt:

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]

Lijstbegrippen zijn efficiënt en kunnen in veel gevallen sneller zijn dan map , dus test de tijden van beide benaderingen als snelheid belangrijk voor u is.

Basisgebruik van map, itertools.imap en future_builtins.map

De kaartfunctie is de eenvoudigste van de ingebouwde Python-functies die worden gebruikt voor functioneel programmeren. map() past een gespecificeerde functie toe op elk element in een iterabel:

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>

Een Python 3-compatibele map is opgenomen in de module 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>

Als alternatief kun je in Python 2 imap van itertools gebruiken om een generator te krijgen

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>

Het resultaat kan expliciet worden omgezet in een list om de verschillen tussen Python 2 en 3 te verwijderen:

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

map() kan worden vervangen door een equivalent lijstbegrip of generatoruitdrukking :

[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>

Elke waarde in een iterabel in kaart brengen

U kunt bijvoorbeeld de absolute waarde van elk element nemen:

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]

Anonieme functie ondersteunt ook het toewijzen van een lijst:

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

of het omzetten van decimale waarden naar percentages:

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]

of dollars omrekenen naar euro's (gegeven een wisselkoers):

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 is een handige manier om parameters van functies te repareren, zodat ze kunnen worden gebruikt met map plaats van lambda of aangepaste functies te maken.

Waarden van verschillende iterables in kaart brengen

Bijvoorbeeld het berekenen van het gemiddelde van elk i element van meerdere iterables:

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]

Er zijn verschillende vereisten als er meer dan één iterabel wordt doorgegeven aan de map afhankelijk van de versie van python:

  • De functie moet zoveel parameters bevatten als er iterables zijn:

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

    TypeError: median_of_three () ontbreekt 1 vereist positioneel argument: 'c'

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

    TypeError: median_of_three () neemt 3 positionele argumenten, maar er werden 4 gegeven

Python 2.x 2.0.1
  • map : de mapping herhaalt zich zolang er nog een iterabel is die nog niet volledig is verbruikt, maar gaat uit van None van de volledig gebruikte iterables:

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

    TypeError: niet-ondersteunde operandtype (n) voor -: 'int' en 'NoneType'

  • itertools.imap en future_builtins.map : de toewijzing stopt zodra een iterabele stopt:

    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
  • De toewijzing stopt zodra een iterabele stopt:

    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]
    

Transponeren met kaart: "None" gebruiken als functieargument (alleen 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' object kan niet worden opgevraagd

Maar er is een oplossing om vergelijkbare resultaten te hebben:

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

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

Series en parallelle kaarten

map () is een ingebouwde functie, wat betekent dat het overal beschikbaar is zonder dat u een 'import'-instructie hoeft te gebruiken. Het is overal beschikbaar, net als print (). Als je naar voorbeeld 5 kijkt, zie je dat ik een import-statement moest gebruiken voordat ik pretty print kon gebruiken (import pprint). Daarom is pprint geen ingebouwde functie

Series in kaart brengen

In dit geval wordt elk argument van de iterable als argument aan de toewijzingsfunctie in oplopende volgorde geleverd. Dit doet zich voor wanneer we slechts één itereerbare kaart hebben en de toewijzingsfunctie een enkel argument vereist.

voorbeeld 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

resulteert in

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

Voorbeeld 2

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

resulteert in

[3, 3, 6, 10]

Parallelle mapping

In dit geval wordt elk argument van de toewijzingsfunctie parallel getrokken uit alle iterabelen (één uit elke iterabele). Het aantal geleverde iterables moet dus overeenkomen met het aantal argumenten dat de functie vereist.

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)

Voorbeeld 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)))

resulteert in

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

Voorbeeld 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)))

resulteert in

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

Voorbeeld 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)))

resulteert 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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow