Posted by Zell_ff8 on Mon 18 May 06:00
report abuse | download | new post
- # -*- encoding: latin1 -*-
- #by zell_ff8
- class _Nodo(object):
- def __init__(self,x=None): self.dato,self.prox=x,None
- def __str__(self): return str(self.dato)
- def __repr__(self): return "_Nodo(%s)"%self.dato
- #-------------------------------------------------------------------------------------
- # class Lista
- #-------------------------------------------------------------------------------------
- class Lista(object):
- """Lista de nodos enlazados. Tiene todas las funciones de 'list' pero
- implementadas para este tipo de lista
- Atributos:
- self.prim => Referencia al primer nodo
- self.len => Cantidad de nodos
- """
- #Basicas
- def __init__(self,*x):
- "Inicializa Lista"
- self.prim=None
- self.len=0
- self.extend(x)
- def __len__(self):
- "x.__len__() <==> x.len"
- return self.len
- def __repr__(self):
- "x.__repr__() <==> repr(x)"
- if not self.len: return "Lista()"
- s="Lista("
- p=self.prim
- while p:
- s+=repr(p.dato)+","
- p=p.prox
- return s[:-1]+")"
- def __str__(self):
- "x.__str__() <==> str(x)"
- if not self.len: return "[] -Lista-"
- s="["
- p=self.prim
- while p:
- s+=str(p.dato)+", "
- p=p.prox
- return s[:-2]+"] -Lista-"
- #Iteradores
- def __iter__(self):
- "x.__iter__() <==> iter(x)"
- p=self.prim
- while p:
- yield p.dato
- p=p.prox
- raise StopIteration
- def __reversed__(self):
- """x.__reversed__() <==> x._invertir().__iter__()"""
- return self._invertir().__iter__()
- #get/set/del item/slice
- def __getitem__(self,i):
- "x.__getitem__(i) <==> x[i]"
- if i<0 and abs(i)<=self.len: i=self.len+i
- if not 0<=i<self.len:
- raise IndexError,"index out of range"
- p=self.prim
- c=0
- while c<i:
- p=p.prox
- c+=1
- return p.dato
- def __getslice__(self,i,j):
- "x.__getslice__(i, j) <==> x[i:j]"
- c=0
- s=self._null()()
- if i<0: i=0
- if j>self.len: j=self.len
- p=self.prim
- while c<j:
- if not p:
- break
- if c>=i:
- s.append(p.dato)
- p=p.prox
- c+=1
- return s
- def __delitem__(self,i):
- "x.__delitem__(i) <==> del x[i]"
- if i<0 and abs(i)<=self.len: i=self.len+i
- if not 0<=i<self.len:
- raise IndexError,"index out of range"
- self.len-=1
- if not i:
- self.prim=self.prim.prox
- return
- c=1
- p=self.prim
- while c<i:
- c+=1
- p=p.prox
- p.prox=p.prox.prox
- def __delslice__(self,i,j):
- "x.__delslice__(i, j) <==> del x[i:j]"
- if i<0:i=0
- if j>=self.len: j=self.len
- if i>j or i==j: return
- c=0
- p=self.prim
- while c<j:
- c+=1
- if c==i:
- start=p
- if c==j:
- end=p
- break
- p=p.prox
- if not i:
- self.prim=end.prox
- else:
- start.prox=end.prox
- self.len-=j-i
- def __setitem__(self,i,y):
- "x.__setitem__(i, y) <==> x[i]=y"
- if i<0 and abs(i)<=self.len: i=self.len+i
- if not 0<=i<self.len:
- raise IndexError,"index out of range"
- p=self.prim
- c=0
- while c<i:
- p=p.prox
- c+=1
- p.dato=y
- def __setslice__(self,i,j,y):
- "x.__setslice__(i,j,y) <==> x[i:j]=y"
- if i<0:i=0
- if j<i:j=i
- if j>self.len:j=self.len
- c=0
- p=self.prim
- self.__delslice__(i,j)
- while p.prox:
- if c+1==i:
- break
- c+=1
- p=p.prox
- end=p.prox
- for item in y:
- if not self.prim or not i:
- self.prim=_Nodo(item)
- p=self.prim
- i=True
- continue
- p.prox=_Nodo(item)
- p=p.prox
- p.prox=end
- self.len+=len(y)
- #Operadores
- def __add__(self,y):
- """x.__add__(y) <==> x+y
- Devuelve lista de igual tipo con 'x', 'y' concatenadas"""
- if not isinstance(y,(Lista,list,tuple)):
- raise TypeError,"can only concatenate iterable type to Lista"
- s=self[:] #crea copia
- for i in y:
- s.append(i)
- return s
- def __iadd__(self,y):
- """x.__add__(y) <==> x+=y
- <Modifica x>"""
- if not isinstance(y,(Lista,list,tuple)):
- raise TypeError,"can only concatenate iterable type to Lista"
- if self is y: y=y[:] #fix de x+=x
- for i in y:
- self.append(i)
- return self
- def __mul__(self,i):
- """x.__mul__(y) <==> x*i
- Devuelve lista de igual tipo con 'x' concatenada 'i' veces."""
- if type(i)!=int:
- raise TypeError,"can't multiply sequence by non-int"
- s=self._null()()
- if i<=0:
- return s
- for x in xrange(i):
- s.extend(self)
- return s
- def __imul__(self,i):
- """x.__imul__(i) <==> x*=i
- <Modifica x>"""
- if type(i)!=int:
- raise TypeError,"can't multiply sequence by non-int"
- s=self[:] #crea una copia
- for x in xrange(i-1):
- self.extend(s)
- return self
- def __rmul__(self,n):
- "x.__rmul__(n) <==> x.__mul__(n)"
- return self.__mul__(n)
- def __eq__(self,y):
- """x.__eq__(y) <==> x==y
- Lista se compara con cualquier iterable. Si x=Lista(...),
- x.__eq__(y)==True cuando 'y' es:
- list(x), tuple(x), ListaO(*x), Lista(*x)
- """
- if len(self)!=len(y):
- return False
- p1=iter(self)
- p2=iter(y)
- while 1:
- try:
- if p1.next()!=p2.next():
- return False
- except StopIteration:
- return True
- def __ne__(self,y):
- "x.__ne__(y) <==> not x==y"
- return not self.__eq__(y)
- def __contains__(self,y):
- "x.__contains__(y) <==> y in x"
- for dato in self:
- if dato==y:
- return True
- return False
- def __idiv__(self,i): #debug) x/=list == list(x)
- "Usado para modificar tipo"
- if i in [list,tuple]:return i(self)
- return i(*self)
- #Internas
- def _invertir(self):
- "Devuelve una nueva 'Lista' en orden inverso."
- revez=Lista()
- p=self.prim
- while p:
- revez.insert(0,p.dato)
- p=p.prox
- return revez
- def _null(self):
- "Devuelve la clase."
- return Lista
- #Métodos
- def append(self,x):
- "Agrega 'x' al final de la Lista."
- self.len+=1
- if self.len==1:
- self.prim=_Nodo(x)
- else:
- p=self.prim
- while p.prox:
- p=p.prox
- p.prox=_Nodo(x)
- return
- def count(self,x):
- "Devuelve cantidad de concurrencias de 'x' en la Lista."
- c=0
- p=self.prim
- while p:
- if p.dato==x:
- c+=1
- p=p.prox
- return c
- def extend(self,l):
- "Agrega cada elemento de 'l' al final ('l' es un iterable)"
- #for item in l: self.append(item) """ muchas operacines
- if not len(l):
- return
- #Caso lista vacia
- if not self.prim:
- self.prim=_Nodo(l[0])
- s=1
- else:
- s=0
- #se ubica al final
- p=self.prim
- while p.prox:
- p=p.prox
- #agrega
- for i in xrange(s,len(l)):
- p.prox=_Nodo(l[i])
- p=p.prox
- self.len+=len(l)
- def find(self,x,start=0,stop=False):
- """Devuelve posición de la primera aparición de 'x' en la Lista.
- Devuelve -1 si no se encuentra."""
- try:
- return self.index(x,start,stop)
- except ValueError:
- return -1
- def index(self,x,start=0,stop=False):
- """Devuelve posición de la primera aparición de 'x' en la Lista.
- Levanta ValueError si no se encuentra."""
- if not stop:
- stop=self.len
- c=0
- p=self.prim
- start=self._adjustIndex(start)
- stop=self._adjustIndex(stop)
- while p:
- if c>=stop:
- break
- if c>=start and p.dato==x:
- return c
- c+=1
- p=p.prox
- raise ValueError,"x.index(x,start,stop): x not in Lista[%s:%s]"%(start,stop)
- def insert(self,i,x):
- "Inserta 'x' antes de la posición 'i'."
- n=_Nodo(x)
- c=0
- self.len+=1
- #Primer elemento
- if i<=0:
- n.prox=self.prim
- self.prim=n
- return
- p=self.prim
- while p:
- if c+1==i or not p.prox:
- break
- c+=1
- p=p.prox
- n.prox=p.prox
- p.prox=n
- def pop(self,i=None):
- """Devuelve el elemento en la posición 'i' y lo elimina de la lista.
- Por defecto toma el último elemento.
- x.pop() -> extrae el último
- x.pop(0) -> extra el primero"""
- if i==None:
- i=self.len-1
- else:
- i=self._adjustIndex(i)
- if not 0<=i<self.len:
- raise IndexError,"pop index out of range"
- self.len-=1
- p=self.prim
- if not i:
- self.prim=p.prox
- return p.dato
- c=1
- while c<i:
- c+=1
- p=p.prox
- s=p.prox.dato
- p.prox=p.prox.prox
- return s
- def remove(self,x):
- """Elimina la primera aparicion de 'x' en la Lista.
- Levanta ValueError si 'x' no se encuentra."""
- if self.prim:
- if self.prim.dato==x:
- self.prim=self.prim.prox
- self.len-=1
- return
- p=self.prim
- while p.prox:
- if p.prox.dato==x:
- p.prox=p.prox.prox
- self.len-=1
- return
- p=p.prox
- raise ValueError,"x.remove(y): y not in x"
- def reverse(self):
- """Invierte la Lista."""
- self.prim=self._invertir().prim
- def sort(self):
- """Ordena la Lista (en realidad crea una ListaO con los
- mismos valores y la transforma en Lista)
- x.sort() <==> x.prim=Lista(*ListaO(*x)).prim"""
- self.prim=Lista(*ListaO(*self)).prim
- #-------------------------------------------------------------------------------------
- # class ListaO
- #-------------------------------------------------------------------------------------
- class ListaO(Lista):
- """ListaO es una Lista que siempre está ordenada. El criterio de
- orden está en el atributo self.func=f
- Siendo f una función que recibe 'a' y 'b', y que devuelve True cuando esta
- permitido insertar 'a' antes que 'b'.
- Por defecto:
- self.func=lambda a,b: a<b
- Atributos:
- self.prim => Referencia al primer nodo
- self.len => Cantidad de nodos
- self.func => Criterio de orden
- """
- #Basicas
- def __init__(self,*x):
- "Inicializa ListaO"
- self.func=lambda a,b:a<b
- Lista.__init__(self,*x)
- def __repr__(self):
- "x.__repr__() <==> repr(x)"
- if not self.len: return "ListaO()"
- s="ListaO("
- p=self.prim
- while p:
- s+=repr(p.dato)+","
- p=p.prox
- return s[:-1]+")"
- def __str__(self):
- "x.__str__() <==> str(x)"
- if not self.len: return "[] -ListaO-"
- s="["
- p=self.prim
- while p:
- s+=str(p.dato)+", "
- p=p.prox
- return s[:-2]+"] -ListaO-"
- #Internas
- def _null(self):
- "Devuelve la clase."
- return ListaO
- #get/set/del item/slice
- def __setitem__(self,i,y):
- """Para mantener el orden, esta función realiza:
- self.__delitem__(i)
- self.insert(y)"""
- self.__delitem__(i)
- self.insert(y)
- def __setslice__(self,i,j,y):
- """Para mantener el orden, esta función realiza:
- self.__delslice__(i,j)
- self.extend(y)"""
- self.__delslice__(i,j)
- self.extend(y)
- #Métodos
- def append(self,x):
- "Sin sentido en ListaO. Llama a self.insert(x) para mantener el orden."
- self.insert(x)
- def extend(self,l):
- "Agrega cada elemento de 'l' de manera ordenada ('l' es un iterable)"
- for item in l: self.insert(item)
- def insert(self,x):
- "Inserta 'x' en la ListaO (en orden según self.func)"
- self.len+=1
- n=_Nodo(x)
- if self.len==1:
- self.prim=n
- return
- p=self.prim
- if self.func(x,p.dato):
- n.prox=p
- self.prim=n
- return
- while p.prox:
- if self.func(x,p.prox.dato):
- break
- p=p.prox
- n.prox=p.prox
- p.prox=n
- def reverse(self):
- """Invierte la ListaO.
- Para mantener el ordenamiento, cambia el criterio de ordenamiento a:
- x=self.func
- self.func=lambda a,b: not x(a,b)
- ...que puede no ser aplicable en todos los casos."""
- Lista.reverse(self)
- x=self.func
- self.func=lambda a,b: not x(a,b)
- def sort(self):
- "Redundante. ListaO siempre está ordenada :)"
- pass
- #------------------------------------------------------------
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.