web-dev-qa-db-fra.com

Comprendre la fonction map

map(function, iterable, ...)

Appliquer la fonction à chaque élément de iterable et retourner une liste des résultats. Si d'autres arguments itérables sont passés, function doit prendre autant d'arguments et est appliqué aux éléments de tous les itérables en parallèle.

Si un itérable est plus court qu'un autre, il est supposé être étendu avec des éléments Aucun.

Si fonction est None, la fonction d'identité est assumée; s'il y a plusieurs arguments, map() renvoie une liste composée de nuplets contenant les éléments correspondants de tous les itérables (une sorte d'opération de transposition).

Les arguments itérables peuvent être une séquence ou tout objet itérable; le résultat est toujours une liste.

Quel rôle cela joue-t-il dans la fabrication d'un produit cartésien?

content = map(Tuple, array)

Quel est l'effet de placer un Tuple n'importe où là-bas? J'ai aussi remarqué que sans la fonction map, la sortie est abc et avec elle, c'est a, b, c.

Je veux bien comprendre cette fonction. Les définitions de référence sont également difficiles à comprendre. Trop de duvet de fantaisie.

280
Web Master

map n'est pas particulièrement Pythonic. Je recommanderais d'utiliser une compréhension de liste à la place:

map(f, iterable)

est fondamentalement équivalent à:

[f(x) for x in iterable]

map ne peut à lui seul produire un produit cartésien, car la longueur de sa liste de sortie est toujours identique à celle de sa liste de saisie. Vous pouvez trivialement faire un produit cartésien avec une liste de compréhension cependant:

[(a, b) for a in iterable_a for b in iterable_b]

La syntaxe est un peu déroutante - cela équivaut fondamentalement à:

result = []
for a in iterable_a:
    for b in iterable_b:
        result.append((a, b))
388
dave

map ne se rapporte pas du tout à un produit cartésien, bien que j'imagine qu'une personne bien initiée à la programmation fonctionnelle puisse trouver un moyen impossible à comprendre de générer un en utilisant map.

map dans Python 3 est équivalent à ceci:

def map(func, iterable):
    for i in iterable:
        yield func(i)

et la seule différence dans Python 2 est qu’il va constituer une liste complète de résultats pour renvoyer tous les éléments en même temps au lieu de yielding.

Bien que la convention Python préfère généralement les interprétations de liste (ou les expressions de générateur) pour obtenir le même résultat qu'un appel à map, en particulier si vous utilisez une expression lambda comme premier argument:

[func(i) for i in iterable]

Comme exemple de ce que vous avez demandé dans les commentaires sur la question - "transformer une chaîne en tableau", par "tableau", vous voulez probablement un tuple ou une liste (les deux se comportent un peu comme des tableaux d'autres langues). -

 >>> a = "hello, world"
 >>> list(a)
['h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd']
>>> Tuple(a)
('h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd')

Une utilisation de map serait ici si vous commencez par une chaîne liste au lieu d'une chaîne unique - map peut les répertorier toutes individuellement:

>>> a = ["foo", "bar", "baz"]
>>> list(map(list, a))
[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']]

Notez que map(list, a) est équivalent en Python 2, mais en Python 3, vous avez besoin de l'appel list si vous souhaitez effectuer autre chose que de l'introduire dans un fichier. La boucle for (ou une fonction de traitement telle que sum ne nécessitant qu'un élément itératif et non une séquence). Mais notons encore qu’une compréhension par liste est généralement préférée:

>>> [list(b) for b in a]
[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']]
80
lvc

map crée une nouvelle liste en appliquant une fonction à chaque élément de la source:

xs = [1, 2, 3]

# all of those are equivalent — the output is [2, 4, 6]
# 1. map
ys = map(lambda x: x * 2, xs)
# 2. list comprehension
ys = [x * 2 for x in xs]
# 3. explicit loop
ys = []
for x in xs:
    ys.append(x * 2)

n-ary map équivaut à compresser ensemble des éléments itérables, puis à appliquer la fonction de transformation à chaque élément de la liste compressée intermédiaire. C'est pas un produit cartésien:

xs = [1, 2, 3]
ys = [2, 4, 6]

def f(x, y):
    return (x * 2, y // 2)

# output: [(2, 1), (4, 2), (6, 3)]
# 1. map
zs = map(f, xs, ys)
# 2. list comp
zs = [f(x, y) for x, y in Zip(xs, ys)]
# 3. explicit loop
zs = []
for x, y in Zip(xs, ys):
    zs.append(f(x, y))

J'ai utilisé Zip ici, mais le comportement de map diffère légèrement lorsque les éléments itérables ne sont pas de la même taille - comme indiqué dans sa documentation, il étend les éléments itérables à None.

33
Cat Plus Plus

En simplifiant un peu, vous pouvez imaginer map() faire quelque chose comme ceci:

def mymap(func, lst):
    result = []
    for e in lst:
        result.append(func(e))
    return result

Comme vous pouvez le constater, il faut une fonction et une liste, puis renvoie une nouvelle liste avec le résultat de l’application de la fonction à chacun des éléments de la liste d’entrée. J'ai dit "simplifier un peu" car en réalité map() peut traiter plus d'un itérable:

Si d'autres arguments itérables sont passés, function doit prendre autant d'arguments et est appliqué aux éléments de tous les itérables en parallèle. Si un itérable est plus court qu'un autre, il est supposé être étendu avec des éléments Aucun.

Pour la deuxième partie de la question: quel rôle cela joue-t-il dans la fabrication d'un produit cartésien? map() pourrait être utilisé pour générer le produit cartésien d'une liste comme celle-ci:

lst = [1, 2, 3, 4, 5]

from operator import add
reduce(add, map(lambda i: map(lambda j: (i, j), lst), lst))

... Mais à vrai dire, utiliser product() est un moyen beaucoup plus simple et naturel de résoudre le problème:

from itertools import product
list(product(lst, lst))

Dans les deux cas, le résultat est le produit cartésien de lst tel que défini ci-dessus:

[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5),
 (2, 1), (2, 2), (2, 3), (2, 4), (2, 5),
 (3, 1), (3, 2), (3, 3), (3, 4), (3, 5),
 (4, 1), (4, 2), (4, 3), (4, 4), (4, 5),
 (5, 1), (5, 2), (5, 3), (5, 4), (5, 5)]
20
Óscar López

La fonction map() est là pour appliquer la même procédure à chaque élément d'une structure de données itérable, telle que des listes, des générateurs, des chaînes et d'autres éléments.

Prenons un exemple: map() peut parcourir tous les éléments d'une liste et appliquer une fonction à chaque élément, puis renvoie (renvoie) la nouvelle liste.

Imaginez que vous ayez une fonction qui prend un nombre, ajoute 1 à ce nombre et le renvoie:

def add_one(num):
  new_num = num + 1
  return new_num

Vous avez également une liste de numéros:

my_list = [1, 3, 6, 7, 8, 10]

si vous souhaitez incrémenter chaque numéro de la liste, vous pouvez procéder comme suit:

>>> map(add_one, my_list)
[2, 4, 7, 8, 9, 11]

Remarque: au minimum map() nécessite deux arguments. D'abord un nom de fonction et ensuite quelque chose qui ressemble à une liste.

Voyons d'autres choses intéressantes que map() peut faire. map() peut prendre plusieurs itérables (listes, chaînes, etc.) et transmettre un élément de chaque itérable à une fonction sous forme d'argument.

Nous avons trois listes:

list_one = [1, 2, 3, 4, 5]
list_two = [11, 12, 13, 14, 15]
list_three = [21, 22, 23, 24, 25]

map() peut vous créer une nouvelle liste contenant l'ajout d'éléments à un index spécifique.

Maintenant, rappelez-vous map(), a besoin d'une fonction. Cette fois, nous utiliserons la fonction intégrée sum(). Lancer map() donne le résultat suivant:

>>> map(sum, list_one, list_two, list_three)
[33, 36, 39, 42, 45]

N'OUBLIEZ PAS:
Dans Python 2 map(), itérera (parcourra les éléments des listes) en fonction de la liste la plus longue, et passera None à la fonction pour la plus courte votre fonction doit donc rechercher None et les gérer, sinon vous obtiendrez des erreurs. Dans Python 3 map() s'arrêtera après avoir terminé avec la liste la plus courte. De plus, dans Python 3, map() renvoie un itérateur, pas une liste.

14
BlooB

Python3 - map (func, iterable)

Une chose qui n’a pas été mentionnée complètement (bien que @BlooB l’ait un peu mentionné) est que map renvoie un objet map NOT une liste. C'est une grande différence en ce qui concerne les performances temporelles d'initialisation et d'itération. Considérons ces deux tests.

import time
def test1(iterable):
    a = time.clock()
    map(str, iterable)
    a = time.clock() - a

    b = time.clock()
    [ str(x) for x in iterable ]
    b = time.clock() - b

    print(a,b)


def test2(iterable):
    a = time.clock()
    [ x for x in map(str, iterable)]
    a = time.clock() - a

    b = time.clock()
    [ str(x) for x in iterable ]
    b = time.clock() - b

    print(a,b)


test1(range(2000000))  # Prints ~1.7e-5s   ~8s
test2(range(2000000))  # Prints ~9s        ~8s

Comme vous pouvez le constater, l’initialisation de la fonction carte ne prend presque pas de temps. Cependant, itérer à travers l'objet de la carte prend plus de temps que simplement itérer à l'itérable. Cela signifie que la fonction transmise à map () n'est appliquée à chaque élément que lorsque l'élément est atteint dans l'itération. Si vous voulez une liste, utilisez la compréhension de liste. Si vous envisagez d'effectuer une itération dans une boucle for et que vous vous interrompez à un moment donné, utilisez map.

4
Ranga