C'est un itérateur. Vous pouvez le convertir en list
ou tuple
en utilisant list(combinations('12345', 3))
ou tuple(combinations('12345', 3))
.
Par votre question je pense vous pouvez avoir une certaine confusion sur ce que sont les séquences, itérations et itérateurs. Je pense qu'il est utile de les comprendre pour pouvoir écrire et/ou comprendre le code python, donc je vais essayer de vous donner une explication à ce sujet.
Les objets list
et tuple
sont séquences. Les séquences sont des objets qui prennent en charge certaines opérations spécifiques. A savoir qu'ils sont iterables (vous pouvez le faire for elem in sequence
), ils soutiennent « l'accès de l'élément » (sequence[key]
est valide) ils ont une « longueur » (len(sequence)
est valide) et vous pouvez vérifier si un article est dans la séquence (elem in sequence
est valide). [Il existe un complete list d'opérations qui constitue le "protocole de séquence". Hélas c'est spécifique pour le C-API. Néanmoins, les noms et les explications de ces fonctions devraient vous donner une idée de l'ensemble des opérations qu'ils soutiennent]
En python, il y a deux autres types d'objets qui, dans certains cas, peut être utilisé à la place de séquences: iterables et itérateurs.
Un itérable est un objet qui prend en charge l'itération. En parlant de python, un objet est itérable s'il a une méthode __iter__
qui retourne un itérateur.
Un itérateur est un objet qui itère une fois sur une itérable et donne les valeurs une par une. En python, un itérateur est un objet qui implémente les méthodes __iter__
et __next__
(next
dans python2). __iter__
habituellement "ne fait rien", renvoie simplement l'objet lui-même. La méthode next
renvoie la valeur suivante dans le itérable.
Maintenant, combinations('12345', 3)
est un itératives, ce qui signifie que vous pouvez passer en boucle, mais vous ne pouvez pas accéder à ses éléments en utilisant la syntaxe iterable[key]
et vous ne pouvez pas obtenir sa longueur avec len
. Pourquoi utiliseriez-vous des itérateurs? Dans certaines situations, vous pouvez éviter d'avoir toute une séquence de valeurs en mémoire pour l'itérer. Par exemple, si vous souhaitez effectuer une boucle sur les numéros 1
à 100
, vous ne devez pas créer un list
de longueur 100
rempli avec les numéros et parcourir par-dessus. Donnez une valeur que vous pouvez calculer en ajoutant 1
. Donc, fondamentalement, les iterables sont un moyen de réduire l'utilisation de la mémoire, et en général sont une abstraction de la fonctionnalité nécessaire pour "boucler quelque chose". Si vous voulez une séquence, vous pouvez les convertir comme indiqué précédemment.
Les générateurs sont des générateurs d'un type particulier d'itérateurs. Les générateurs sont tout simplement itérateurs qui peuvent être écrits en utilisant la fonction syntaxe, en particulier, ils utilisent le mot-clé yield
:
>>> def numbers(n):
... while n > 0:
... yield n
... n -= 1
...
>>> numbers(5)
<generator object numbers at 0xb744a93c>
>>> for elem in numbers(5):
... print elem
...
5
4
3
2
1
Comme vous pouvez le voir lorsque vous appelez numbers
le code est pas Execute. Au lieu de cela, python crée un objet générateur, qui est un itérateur. Lorsque vous parcourez l'objet, le code à l'intérieur de la fonction est exécuté jusqu'à ce que le yield
soit rencontré. Lorsque cela se produit, l'argument "yield
" est renvoyé et l'exécution est gelée. Quand une nouvelle itération commence, elle recommence.
Probablement vous pouvez mieux voir le flux d'exécution dans cet exemple:
>>> def flow():
... yield 'Execution stopped here'
... yield 'Execution continues'
... yield 'Execution ended'
...
>>> generator = flow()
>>> next(generator) #same as generator.__next__()
'Execution stopped here'
>>> next(generator)
'Execution continues'
>>> next(generator)
'Execution ended'
>>> next(generator)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
Vous pourriez être intéressé par l'PEP255 où ils ont été proposés. En fait, ils ont été étendus pour fournir des fonctionnalités coroutines, mais je pense que cela suffit pour le moment.
Techniquement, pas un générateur, juste un itérable (d'une classe manuscrite). Mais oui, cela pourrait aussi bien être mis en œuvre en tant que générateur. – delnan
[OP] Merci, je me suis débrouillé seul quelques minutes après avoir posé la question. Je n'ai pas réalisé que 'combinations' renvoie un itérateur par opposition à la liste actuelle. J'ai également compris que l'appel 'list()' sur un itérateur retournera une liste réelle. Merci!! – jayhendren
@delnan: merci, j'ai corrigé mon message – Nicolas