web-dev-qa-db-fra.com

Comment appliquer une fonction aux éléments d'une liste?

Je souhaite appliquer une fonction à tous les éléments de la liste, mais je souhaite réellement modifier les éléments (qui sont des objets) et non afficher les résultats. Je pense que c’est le problème de l’utilisation de map() ou de la compréhension de liste.

class Thing(object):
    pass

# some collection of things
my_things

# they are all big...

# produces SyntaxError: invalid syntax
[i.size = "big" for i in my_things]

# produces SyntaxError: lambda cannot contain assignment
map(lambda i: i.size="big", [i for i in my_things]) 

# no error, but is it the preferred way?
for i in my_things:
    i.size="big"

Quel est le moyen de faire cela?

12
cammil

Et quel est le problème avec

for i in my_things:
    i.size = "big"

Vous ne voulez pas utiliser ni la variable map ni la liste comprehansion car elles créent en fait de nouvelles listes. Et vous n'avez pas besoin de ces frais généraux, n'est-ce pas?

15
freakish

Bien que je convienne qu'il n'y a rien de mal à 

for i in my_things:
    i.size = "big"

certaines personnes sont excitées par les one-liners python. ;)

Une option consiste à ajouter une méthode set à votre classe, qui peut ensuite être appelée à partir de lambda (essentiellement en masquant l'affectation dans une fonction):

class Thing(object):
    def setSize(self, size):
        self.size = size

map(lambda i: i.setSize("big"), my_things) 
11
DirkR

Vous pouvez utiliser la méthode __setattr__ pour affecter l'attribut dans une liste de compréhension. Bien que, selon certains SO threads, utiliser des interprétations de liste sans utiliser la sortie ne soit pas Pythonic. 

[i.__setattr__('size', 'big') for i in my_things]
2
garnertb

Je pense que c'est le problème avec l'utilisation de map () ou de compréhension de liste.

Pas entièrement.

my_things[:] = map(...)

peut-être comme ça sur python3:

[dict(**i.__dict__, size='big') for i in my_things]

ou

map(lambda x: dict(**x.__dict__, size='big'), my_things)

si je ne dicte pas d'objection

[dict(**i, size='big') for i in my_things]

sur python2

[dict(i.copy(), size='big') for i in my_things]  # isinstance(i, dict)
[dict(i.__dict__.copy(), size='big') for i in my_things]  # isinstance(i, object)
0
mackjoner