Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

action sur une sous liste

4 réponses
Avatar
François Couloigner
Bonjour,
Je dispose d'un fonction f(l) dont le paramètre est une liste l de
longueur n dont les éléments sont modifiés par la fonction.

Dans le programme principal, j'ai une liste L et je souhaite appliquer f
aux éléments de rangs ai+b pour tout i de 0 à n-1. Bref J'aimerais
créer un alias de cette sous liste pour agir sur certains éléments de L
sans modifier les autres.

Par exemple L=[0,1,2,3,4,5,6,7,8,9,10] , et je souhaite appliquer un
traitement aux rangs 1,4,7,10 ou une autre fois aux rangs 4,6,8,10.
La fonction f peut par exemple être le cumul de valeurs (1,4,7,10 donne
1,5,12,22 )

Comment faire ?

4 réponses

Avatar
Nicolas
Le 01/06/2015 21:45, François Couloigner a écrit :
Bonjour,
Je dispose d'un fonction f(l) dont le paramètre est une liste l de
longueur n dont les éléments sont modifiés par la fonction.

Dans le programme principal, j'ai une liste L et je souhaite appliquer f
aux éléments de rangs ai+b pour tout i de 0 à n-1. Bref J'aimerais créer
un alias de cette sous liste pour agir sur certains éléments de L sans
modifier les autres.

Par exemple L=[0,1,2,3,4,5,6,7,8,9,10] , et je souhaite appliquer un
traitement aux rangs 1,4,7,10 ou une autre fois aux rangs 4,6,8,10.
La fonction f peut par exemple être le cumul de valeurs (1,4,7,10 donne
1,5,12,22 )

Comment faire ?



Un exemple parmi d'autres pour générer la sous liste:

def gen_sous_liste(l, a, b):
# Retourne les indices a*i+b
# Ne fonctionne qu'avec a >= 1
sl = []
for i in range(len(l)) :
try :
sl.append(l[a*i+b])
except IndexError :
break
return sl

l=[0,1,2,3,4,5,6,7,8,9,10]
sl1 = gen_sous_liste(l, 3, 1) # -> [1, 4, 7, 10]
sl2 = gen_sous_liste(l, 2, 4) # -> [4, 6, 8, 10]

Ensuite, appeler f() avec sl.
Avatar
Alain Ketterlin
François Couloigner writes:

Je dispose d'un fonction f(l) dont le paramètre est une liste l de
longueur n dont les éléments sont modifiés par la fonction.



Ce n'est pas possible en général, puisque certains élém ents sont
immuables (les entiers, les tuples, etc.)

Dnoc je suppose que tu veux que la liste originale soit modifiée à
certaines positions. Le plus simple est de passer cet ensemble de
positions à f :

def f(l,pos):
for p in pos:
l[p] = ...

Dans le programme principal, j'ai une liste L et je souhaite appliquer
f aux éléments de rangs ai+b pour tout i de 0 à n-1.



Bon, f s'applique à la liste ou aux éléments ?

Bref J'aimerais créer un alias de cette sous liste pour agir sur
certains éléments de L sans modifier les autres.



Si c'est cela que tu veux faire, alors il faut définir toi-même u ne
classe qui cache dans L ce qui ne doit pas modifié. Cette classe doit
comporter les méthodes __getitem__() et __setitem__() (et éventue llement
d'autres selon ce que tu veux vraiment faire avec -- c'est-à-dire selon
ce que fait f()). Par exemple :

class View:
def __init__(self,master,indices):
self.master = master
self.indices = indices[:]
def __getitem__(self,i):
return self.master[self.indices[i]]
def __setitem__(self,i,v):
return self.master[self.indices[i]] = v

(Bien sur, je n'ai rien testé.) Voir à

https://docs.python.org/2/reference/datamodel.html#emulating-container-types

tout ce qu'il faut écrire pour avoir un container qui respect le
protocole standard.

Avec cette solution, gare aux manipulations concurrentes de la liste
original et d'une ou plusieurs vues.

Par exemple L=[0,1,2,3,4,5,6,7,8,9,10] , et je souhaite appliquer un
traitement aux rangs 1,4,7,10 ou une autre fois aux rangs 4,6,8,10.



f(View(L,[1,4,7,10])) ou f(View(L,xrange(1,len(L),3)))

(Note que je parle python 2. Le but du dernier exemple est montrer qu'on
peut passer un générateur au constructeur,, mais qu'il est parcou ru
entièrement à ce moment-là.)

La fonction f peut par exemple être le cumul de valeurs (1,4,7,10
donne 1,5,12,22 )



Ça ne correspond pas à ce que tu demandes plus haut : faut-il agi r sur
la liste, sur chaque élément, ou bien simplement parcourir/sommer /...
les éléments ?

-- Alain.
Avatar
François Couloigner
Le 01/06/2015 21:45, François Couloigner a écrit :
Bonjour,
Je dispose d'un fonction f(l) dont le paramètre est une liste l de
longueur n dont les éléments sont modifiés par la fonction.

Dans le programme principal, j'ai une liste L et je souhaite appliquer f
aux éléments de rangs ai+b pour tout i de 0 à n-1. Bref J'aimerais créer
un alias de cette sous liste pour agir sur certains éléments de L sans
modifier les autres.

Par exemple L=[0,1,2,3,4,5,6,7,8,9,10] , et je souhaite appliquer un
traitement aux rangs 1,4,7,10 ou une autre fois aux rangs 4,6,8,10.
La fonction f peut par exemple être le cumul de valeurs (1,4,7,10 donne
1,5,12,22 )

Comment faire ?


Merci de vos réponses. Je n'ai pas été très clair sur l'objectif et
détaille donc l'exemple .

def f(x) : # x est une liste
for i in range(1,len(x)) :
x[i]=x[i]+x[i-1]

l=[1,2,3,4,5,6,7,8,9]
.......

et là je coince
Par exemple l'imaginais possible que la fonction soit appliquée aux
éléments de rangs pairs de l
c'est à dire que l devienne [1,2,3,6,5,12,7,20,9] en utilisant un objet
l' construit à partir de l, lui appliquer f et que ça modifie aussi l.

Je comprends avec votre aide qu'il sera plus simple de créer de
nouvelles listes et de faire des "copies" d'éléments
Avatar
Alain Ketterlin
François Couloigner writes:

Merci de vos réponses. Je n'ai pas été très clair sur l'objectif et
détaille donc l'exemple .

def f(x) : # x est une liste
for i in range(1,len(x)) :
x[i]=x[i]+x[i-1]

l=[1,2,3,4,5,6,7,8,9]
.......

et là je coince
Par exemple l'imaginais possible que la fonction soit appliquée aux
éléments de rangs pairs de l
c'est à dire que l devienne [1,2,3,6,5,12,7,20,9] en utilisant un
objet l' construit à partir de l, lui appliquer f et que ça mo difie
aussi l.



Pour moi les rangs pairs de l forment la liste [1,3,5,7,9] (les listes
sont indicées à partir de 0), donc f calcule [1,4,9,16,25], et do nc
après l'appel de f la liste l devrait contenir
[1,(2),4,(4),9,(6),16,(8),25]. J'ai mis des parenthèses autour des
éléments qui ne sont pas concernés.

Je comprends avec votre aide qu'il sera plus simple de créer de
nouvelles listes et de faire des "copies" d'éléments



La solution donnée dans mon message précédent fonctionne, à condition de
supprimer les erreurs grossières, et d'ajouter __len__, soit :

class View:
def __init__(self,master,indices):
self.master = master
self.indices = indices[:]
def __len__(self):
return len(self.indices)
def __getitem__(self,i):
return self.master[self.indices[i]]
def __setitem__(self,i,v):
self.master[self.indices[i]] = v

def f(x) : # x est une liste
for i in range(1,len(x)) :
x[i]=x[i]+x[i-1]

l=[1,2,3,4,5,6,7,8,9]
v = View(l,range(0,len(l),2))
f(v)
print l

-- Alain.