Bienvenue sur IndexError.

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

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

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

intervertir une liste d' objets

+2 votes

je cherche une façon pythonique et directe pour intervertir une liste d' objets graphiques
(éléments clickables ou non de la librairie thorpy / pygame).

par exemple :
mesboutons = [bouton0,bouton1,bouton2,bouton4,bouton3,bouton5]
y'a t il une meilleure façon que ceci:

tmp_obj = mesboutons[3]
mesboutons[3] = mesboutons[4]
mesboutons[4] = tmp_obj

je cherche une formule du genre

mesboutons.intervert(3,4)

La méthode insert expose au même problème, je veux éviter des copies inutiles, en c++ y'aurait une manip sur les pointeurs.
Pour le jour où je manipule des objets lourds.

demandé 22-Jan par buffalo974 (2,608 points)

Note: il n'y a pas de copie dans le code que tu donnes. Aucun souci avec des objets lourds donc, c'est seulement les références qui sont échangées.

3 Réponses

+5 votes
 
Meilleure réponse

Tu peux faire :

mesboutons[3], mesboutons[4] = mesboutons[4], mesboutons[3]

Swap en une seule opération, c'est pythonique.

répondu 23-Jan par Tiger-222 (584 points)
sélectionné 23-Jan par buffalo974
+1 vote

Utilise des slices :

>>> mesboutons = ['bouton0', 'bouton1', 'bouton2', 'bouton4', 'bouton3', 'bouton5']
>>> mesboutons[3:5] = mesboutons[4:2:-1]
>>> mesboutons
['bouton0', 'bouton1', 'bouton2', 'bouton3', 'bouton4', 'bouton5']
répondu 24-Jan par Simpom

y'a t il un avantage quelconque en passant par les slices, car je trouve
cette écriture moins intuitive ?

Pour échanger deux valeurs, pas d'intérêt à mon sens. Cela devient plus intéressant pour changer l'ordre de plus de valeurs.

+1 vote

La bonne réponse est celle de Tiger-222.
Néanmoins, si le nombre d'objets à inverser est grand ou variable, l'énumération est peu pratique, d'où la réponse de Simpom.

Voici une variante que j'aime bien : elle permet d'implémenter le comportement généralisé de ta fonction hypothétique intervert.

>>> l = [1, 2, 3, 4, 5]
>>> l[2:5] = reversed(l[2:5])
>>> l
[1, 2, 5, 4, 3]

La fonction apply_to_slice se déduit :

def apply_to_slice(it, start, end, function):
    it[start:end] = function(it[start:end])
    return it  # for convenience

def intervert(it, start, end):
    return apply_to_slice(it, start, end, reversed)
répondu 17-Fev par lucas (2,250 points)

hmmm si on fait comme ça et que la liste [start:end] fait plus de trois éléments ça va poser problème du fait que les éléments "centraux" seront inversés:

>>> l = [1, 2, 3, 4, 5]
>>> l[1:5] = reversed(l[1:5])
>>> l
[1, 5, 4, 3, 2]

ça peut servir en effet, je garde ça sous le coude

...