• [^] # Re: Ruby

    Posté par . En réponse au journal A mort les boucles. Évalué à 2.

    > Ha bon pourtant xrange(y)[x]=x, ou j'ai pas suivit quelque chose...
    cf:
    > (bon, ça, c'est la théorie, en pratique, xrange peut te calculer immédiatement un élément quelconque, mais c'est une optimisation spécifique à xrange)

    Bon, d'accord, pour le reste, je me suis royalement embrouillé, j'admets: j'ai joyeusement mélangé xrange et son itérateur...

    Il fallait donc lire:
    >>> x = iter(xrange(5))
    >>> print x
    <rangeiterator object at 0xb7c213e0> # C'est mieux, effectivement ;)
    >>> x.next()
    0
    >>> x.next()
    1
    >>> for i in x:
    ... print i
    2
    3
    4
    >>>

    > le xrange que tu decrit serait plutot une liste chainée...
    Alors là pas du tout:
    - xrange n'est qu'une fonction qui génère des nombres et qui peut fournir un itérateur
    - le xrange que je décrivait était un itérateur, qui n'a rien à voir avec une liste chainée.
    En gros: une liste chainée, c'est grosso modo comme un tableau: tu la construits, puis tu l'utilises
    L'objectif de l'itérateur est de construire les éléments "à la demande" et de ne rien garder en mémoire (histoire de ménager la mémoire, justement). L'intérêt par rapport à la liste chainée est de ne pas avoir à construire des éléments dont on a pas besoin et de garder une empreinte mémoire faible.

    Pour être imagé, tu peux voir une liste chainée comme une matrice ligne à N éléments, et un itérateur comme une suite récurrente. D'ailleurs, voilà ce que je peux faire avec les itérateurs, qui est impossible avec les tableaux:
    class naturels:
    def __init__(self): self._i = 0
    def __iter__(self): return self
    def next(self): i = self._i ; self._i += 1 ; return i

    for i in naturels():
    if est_premier(i): print i

    En gros, je viens de faire une sorte de range(0, infinity). Tu remarqueras que l'appel construction de naturels() ne prend ni un temps infini ni un espace mémoire infini.
    Avec un tableau (ou une liste chainée), tu aurais été obligé de construire un tableau contenant tous les naturels (ça t'aurait pris un temps infini, mais bien heureusement, ta mémoire sera saturée bien avant) avant de pouvoir itérer dessus.

    Tiens, un exemple amusant qui me vient à l'esprit: c'est équivalent à:
    class premiers(naturels):
    def next(self):
    i = naturels.next(self)
    if est_premier(i): return i
    else: return self.next()

    for i in premiers():
    print i

    > D'ailleurs il semble que on ne peut rien affecter dans un xrange :
    Avec une liste chainée, tu pourrais...