fonction range et boucle 'for'

fonction range et boucle 'for' - Python - Programmation

Marsh Posté le 21-01-2014 à 20:11:14    

Bonjour,
 
Je n'ai pas saisi l'approche fonctionnelle de 'for' : Pouvez-vous me l'expliquer ?
 
>>> U=[[x*y for x in range(3)] for y in range(3)]
>>> U
[[0, 0, 0], [0, 1, 2], [0, 2, 4]]
 
J'ai essayé de comprendre en utilisant print mais çà ne me renseigne pas beaucoup :
 
 
>>> print([i*j for j in range(3)])
[0, 2, 4]
>>> print([i*j for i in range(3)])
[0, 2, 4]

Reply

Marsh Posté le 21-01-2014 à 20:11:14   

Reply

Marsh Posté le 21-01-2014 à 21:39:00    

google "list comprehension" si tu veux des explications sur le sujet. Dive in python a aussi un très bon chapitre sur le sujet
 
range(x) est un générateur qui renvoit une suite de nombre de 0 à x. Tu peux en faire une liste via list(range(x)) pour voir simplement ce que ça renvoie
 
la construction for x in range(y) va donc créer une simple boucle, où à chaque itération x va valoir la nouvelle valeur renvoyée par le générateur
 
gnagnagna(x) for x in range(y) va executer la fonction gnagnagna pour chaque valeur de x, à chaque itération. Les crochets autour de l'expression font que l'ensemble va te renvoyer une liste, qui contiendra les valeurs retournées par gnagnagna(x)
tu peux simplement le vérifier avec une fonction toute bête, genre print x for x in range(3) (ou print(x) si tu es en python3), qui va t'imprimer :
0
1
2
[None, None, None]
(à chaque passage print fait son job et affiche la valeur de x, mais print ne renvoyant rien, après 3 passages la liste renvoyée contient donc None, None, None.
 
Donc si on recompose :
b = [x*2 for x in range(3)] va donc faire 3 itérations (à cause du range(
3) qui va renvoyer, 0, puis 1, puis 2, puis s'éteindre)
A chaque itération :
- x va prendre la valeur renvoyée par range
- x*2 va être calculé, puis inséré dans la liste qui sera renvoyée à la fin par l'expression
 
on va donc obtenir : [0, 2, 4], soit 0*2, 1*2, 2*2.
 
Ton expression combine 2 list comprehension, mais le principe reste le même. Cependant l'imbrication des crochets fait que l'expression va renvoyer une liste contenant 3 listes (le 3 dépend de la valeur du range de droite), chaque liste contenant 3 valeur (le 3 dépend du range du milieu)
 
 


---------------
Jubi Photos : Flickr - 500px
Reply

Marsh Posté le 21-01-2014 à 22:54:27    

Merci pour cette explication détaillée  :jap:  
 

Code :
  1. >>> for x in range(y) : print (x)
  2. 0
  3. 1
  4. >>> range(x)
  5. [0]
  6. >>> range(y)
  7. [0, 1]
  8. >>> list(range(x))
  9. [0]
  10. >>> [x for x in range(y)]
  11. [0, 1]
  12. >>> [x for x in range(3)]
  13. [0, 1, 2]


 
 
_Donc pour obtenir une matrice O = [[1,2,3],[4,5,6]]  :
je dois ajouter la bonne valeur à chaque membre de range() " (ce que l'on pourrait appeler le "décalage" ) , en utilisant le paramètre step de range.
 
Comme range() crée une liste, je peux utiliser un mix des deux , non ??
 
 
>

Code :
  1. >> [x for x in [4,5,6]]
  2. [4, 5, 6]
  3. >>> [[x+y for x in [1,2,3]] for y in range(2)]
  4. 12 [[1, 2, 3], [2, 3, 4]]


 

Reply

Marsh Posté le 23-01-2014 à 22:07:16    

Pour ta matrice, le plus simple est d'implémenter une fonction qui prend une liste continue et répartit sur les lignes d'une matrice, genre

Code :
  1. def chunks(coll, n):
  2.    return [coll[i:i+n] for i in range(0, len(coll), n)]


Code :
  1. >>> chunks(range(1, 7), 3)
  2. [[1, 2, 3], [4, 5, 6]]


à noter que les listcomps supportent directement les itérations imbriquées,

Code :
  1. [[x*y for x in range(3)] for y in range(3)]


peut être réécrit

Code :
  1. [x*y for x in range(3) for y in range(3)]


Message édité par masklinn le 23-01-2014 à 22:09:06

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 24-01-2014 à 14:08:26    

Merci beaucoup , c'est une trés bonne idée  :ange: ! La méthode slice et len sont bien utilisées , comme cela prends tous les paramètres en compte "ligne et colonne".
En plus , l'approche fonctionnelle est superbement réalisé mais comment t'es venu l'idée de faire "coll[i:i+n]" , ton astuce est très imbriqué  :love:  
En plus , comme la fonction range() peut prendre 3 arguments , len() c'est comme le 'stop 'et donc le nombre de colonne dépendra de ce paramètre et 'step' donc n , c'est le nombre de ligne que l'on choisira .
 

Code :
  1. >>> def chunks(coll, n):
  2. return [coll[i:i+n] for i in range(0, len(coll), n)]
  3. >>> chunks(range(1, 7), 2)
  4. [[1, 2], [3, 4], [5, 6]]
  5. >>> chunks(range(1, 7), 3)
  6. [[1, 2, 3], [4, 5, 6]]
  7. >>> chunks(range(1, 10), 3)
  8. [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed