Sök…


Syntax

  • karta (funktion, iterable [, * extra_iterables])
  • future_builtins.map (funktion, iterable [, * extra_iterables])
  • itertools.imap (funktion, iterable [, * extra_iterables])

parametrar

Parameter detaljer
fungera funktion för kartläggning (måste ta så många parametrar som det finns iterables) (endast positionellt )
iterable funktionen tillämpas på varje element i det iterable (endast positionellt )
* additional_iterables se iterable, men så många du vill ( valfritt , endast positionellt )

Anmärkningar

Allt som kan göras med map kan också göras med comprehensions :

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

Även om du skulle behöva zip om du har flera iterables:

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]

Listförståelser är effektiva och kan vara snabbare än map i många fall, så testa tiderna för båda metoderna om hastighet är viktig för dig.

Grundläggande användning av karta, itertools.imap och future_builtins.map

Kartfunktionen är den enklaste bland Python-inbyggda apparater som används för funktionell programmering. map() tillämpar en specificerad funktion på varje element i en iterable:

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>

En Python 3-kompatibel map ingår i future_builtins modulen:

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>

Alternativt kan man i Python 2 använda imap från itertools att få en generator

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>

Resultatet kan uttryckligen konverteras till en list att ta bort skillnaderna mellan Python 2 och 3:

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

map() kan ersättas med en motsvarande listaförståelse eller generatoruttryck :

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

Kartlägga varje värde i en iterable

Till exempel kan du ta absolutvärdet för varje element:

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]

Anonym funktion stödjer också för att kartlägga en lista:

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

eller konvertera decimalvärden till procenttal:

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]

eller konvertera dollar till euro (med tanke på en växelkurs):

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 är ett bekvämt sätt att fixa parametrar för funktioner så att de kan användas med map istället för att använda lambda eller skapa anpassade funktioner.

Kartlägga värden för olika iterables

Till exempel att beräkna medelvärdet för varje i element i flera 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]

Det finns olika krav om mer än en iterable skickas till map beroende på versionen av python:

  • Funktionen måste ta så många parametrar som det finns iterables:

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

    TypeError: median_of_three () saknas 1 obligatoriskt positionsargument: 'c'

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

    TypeError: median_of_three () tar 3 positionsargument men 4 gavs

Python 2.x 2.0.1
  • map : Kartläggningen iterates så länge en iterable fortfarande inte är helt konsumerad men antar None från de helt konsumerade iterables:

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

    TypeError: operandtyp (er) som inte stöds för -: 'int' och 'NoneType'

  • itertools.imap och future_builtins.map : Kartläggningen stannar så snart en iterable slutar:

    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
  • Kartläggningen stoppar så snart en iterable slutar:

    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]
    

Transponering med karta: Använd "Ingen" som funktionsargument (endast 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' -objektet kan inte kallas

Men det finns en lösning med liknande resultat:

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

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

Serier och parallellkartläggning

map () är en inbyggd funktion, vilket innebär att den finns överallt utan att behöva använda ett "import" -förklaring. Det finns överallt precis som tryck () Om du tittar på exempel 5 ser du att jag var tvungen att använda ett importmeddelande innan jag kunde använda vackert tryck (importera pprint). Således är inte utskrift en inbyggd funktion

Seriekartläggning

I detta fall tillhandahålls varje argument i den iterable som argument till mappningsfunktionen i stigande ordning. Detta uppstår när vi bara har en iterable att kartlägga och kartläggningsfunktionen kräver ett enda argument.

Exempel 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

resulterar i

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

Exempel 2

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

resulterar i

[3, 3, 6, 10]

Parallell kartläggning

I detta fall dras varje argument för mappningsfunktionen parallellt över alla iterables (ett från varje iterable). Således måste antalet iterables som levereras matcha antalet argument som krävs av funktionen.

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)

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

resulterar i

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

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

resulterar i

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

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

resulterar i

 ['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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow