2011-04-03 3 views
1

J'essaie d'apprendre ce que les itérateurs et les générateurs sont en python, en passant par un tutoriel trouvé en ligne qui utilisait cet itérateur fibonacci par exemple. J'ai des problèmes avec le commentaire sur les lignes 9-11. Qu'est-ce que cela signifie que "les anciennes valeurs de self.fn1 et self.nf2 sont utilisées pour assigner la nouvelle valeur"? Je comprends que les tuples sont des objets immuables mais je ne vois pas pourquoi utiliser tuple est préféré à une liste. Je suppose que je ne vois pas pourquoi l'aide d'un tuple ici est mieux que d'utiliser une liste et je voudrais mieux comprendre si quelqu'un peut aider à expliquer:/essayer de comprendre pourquoi un tuple est préféré à une liste pour un exemple python spécifique (à partir d'un tutoriel)

4 class fibnum: 
5  def __init__(self): 
6  self.fn2 = 1 # "f_{n-2}" 
7  self.fn1 = 1 # "f_{n-1}" 
8  def next(self): # next() is the heart of any iterator 
9  # note the use of the following tuple to not only save lines of 
10  # code but also to insure that only the old values of self.fn1 and 
11  # self.fn2 are used in assigning the new values 
12  (self.fn1,self.fn2,oldfn2) = (self.fn1+self.fn2,self.fn1,self.fn2) 
13  return oldfn2 
14 def __iter__(self): 
15  return self 

de: http://heather.cs.ucdavis.edu/~matloff/Python/PyIterGen.pdf

+0

Le commentaire utilise également incorrectement "assurer". –

+0

Je vous suggère d'éviter ce tutoriel. Son style de codage est moche et non conforme au PEP8. La section suivante fait 'de fib import *'. Ca suffit pour moi. –

+0

bien, mal essayer de chercher quelque chose de différent. c'était juste le premier tutoriel sur ce sujet que j'ai trouvé. – john

Répondre

1

Il n'y a pas d'intérêt à utiliser ici un list, parce que vous êtes toujours face à trois éléments , plutôt qu'un nombre variable d'entre eux. Par « assurer [sic] que seules les anciennes valeurs de self.fn1 et self.fn2 sont utilisés pour attribuer les nouvelles valeurs », le programmeur semble comparer cette méthode à l'alternative:

self.fn1 = X 
self.fn2 = Y 
oldfn2 = Z 

qui ne fonctionnerait pas sur la case depuis self.fn1 est réaffectée avant que son ancienne valeur puisse être affectée à self.fn2. La réorganisation des affectations peut résoudre ce problème, mais avec l'attribution de tuple, vous n'avez pas à vous soucier de la commande.

Cela aurait pu être écrit sans parens, BTW:

self.fn1, self.fn2, oldfn2 = self.fn1+self.fn2, self.fn1, self.fn2 
+0

ok pense que j'ai conclu ici que c'est juste un commentaire déroutant car il n'y aurait aucune différence entre l'utilisation d'un tuple et la liste. Je pense aussi que votre chemin est plus lisible. Merci! – john

2

C'est pas de différence de fonctionnalité ici entre l'utilisation d'un tuple par rapport à un list. Le point qu'ils essaient de faire est qu'il est bon de le faire en une seule déclaration.

Si vous deviez diviser cette ligne unique en plusieurs déclarations, vous finiriez avec quelque chose comme:

oldfn2 = self.fn2 
self.fn2 = self.fn1 
self.fn1 = self.fn1 + oldfn2 
return oldfn2 
+0

droit mais vous pouvez également mettre dans une ligne comme ceci: – john

+0

en une ligne comme ceci: [self.fn1, self.fn2, oldfn2] = [self.fn1 + self.fn2, self.fn1, self.fn2] – john

+0

Oui, d'où la première phrase de ma réponse. –

0

Le commentaire signifie qu'au lieu d'utiliser de multiples tâches comme ceci:

# would be incorrect 
self.fn1 = self.fn1+self.fn2 # because fn1 is overwritten here 
self.fn2 = self.fn1 
oldfn2 = self.fn2 

ils utilisent l'affectation de tuple:

(self.fn1,self.fn2,oldfn2) = (self.fn1+self.fn2,self.fn1,self.fn2) 

qui est plus courte et a également veillé à ce que toutes les nouvelles valeurs sont calculées avant le sapin st attribution arrive.

Questions connexes