Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Modifier un itérable en place

+5 votes

Existe-t-il une manière plus pythonique d'écrire :

for key, value in my_dict.items():
    if condition(key, value):
        my_dict[key] = calculate_1(key, value)

Par exemple, la forme suivante est-elle préférable ?

def calculate_2(key, value):
    if condition(key, value):
        return calculate_1(key, value)
    else:
        return value

my_dict = {key: calculate_2(key, value) for key, value in my_dict.items()}
demandé 21-Jun-2015 par sobriquet

Petite précision par rapport au titre de la question. La première solution est effectivement une modification en place. Par contre la 2eme solution construit un nouveau dictionnaire et n'est donc pas "en place".
Dans le premier cas, toutes les références vers my_dict verront la version modifiée du dictionnaire. Ce n'est pas le cas avec la seconde solution.

Toujours en ce qui concerne le titre: modifier un itérable en place au cours d'une itération est bien souvent une très mauvaise idée.
Ici, ça va parce qu'on ne fait que remplacer la valeur d'une clé, mais ajouter ou supprimer des éléments pendant une itération mène souvent à des bugs vicieux.

2 Réponses

+4 votes
 
Meilleure réponse

Non, faut pas chercher midi à 14h, ton code est très bien. Il est performant et facile à lire. Que demander d'autre ?

répondu 21-Jun-2015 par Sam (5,000 points)

Je suis d'accord. Il ne faut pas se compliquer la vie, trois lignes pour un update de dictionnaire, c'est juste ce qu'il faut.

Il ne faut pas s'imaginer que faire en plus court (ou en plus long) est "mieux", c'est même plutot un jeu à la con de faire des 'one-liners'.

+3 votes

Voilà une écriture qui marche bien pour les dictionnaires :

my_dict.update({key: calculate_1(key, value)
    for key, value in my_dict.items()
    if condition(key, value)})

Elle ne semble pas généralisable aux listes ou tuples.

répondu 21-Jun-2015 par sobriquet
...