2009-11-24 16 views
11

Si tengo una lista en python, ¿cómo puedo crear una referencia a parte de la lista? Por ejemplo:Referencia a parte de la lista - Python

myList = ["*", "*", "*", "*", "*", "*", "*", "*", "*"] 

listPart = myList[0:7:3] #This makes a new list, which is not what I want 

myList[0] = "1" 

listPart[0] 

"1" 

¿Es esto posible y, de ser así, cómo lo codificaré?

Cheers, Joe

+0

También vea http://stackoverflow.com/questions/3485475/can-i-create-a-view-on-a-python-list –

Respuesta

1

creo que es imposible. Llevaría a muchos posibles errores, por ejemplo: ¿qué sucede cuando anexas la lista que hace referencia a una parte de una lista más grande? ¿Deberá reemplazarse o insertarse el siguiente elemento de la lista grande?

Por lo que sé, silce es un mecanismo interno para obtener elementos de la lista. No crean un nuevo objeto de lista, haciendo referencia a partes de un objeto de lista anterior. Islice solo itera sobre los elementos dados por slice, tampoco es la referencia, sino el objeto real - cambiarlo no afecta la lista original. ¿O estoy equivocado?

Como en el comentario, y esa solución contribuye realmente al Sr. Bastien, que puede hacer:

sliceobject = slice(0,7,3) 
for i in xrange(sliceobject.start, sliceobject.stop, sliceobject.step) 
    myList[i] = whatever 

De esta manera se puede acceder a cada elemento especificado de la lista de referencia.

+0

Creo que tiene razón. Pero a mí me parece que algo así como una tupla (lista, sector) podría ajustarse a las necesidades de OP. –

+0

Con suerte. Otra opción podría ser el uso de corte a mano (para i en xrange (sliceobject.start, sliceobject.stop, sliceobject.step) mylist [i] = lo que sea) –

2

No hay nada en Python que realmente haga lo que quiere. Básicamente, quieres escribir algún tipo de objeto proxy.

3

Puede escribir un tipo de lista. Aquí es algo que he escrito como experimento, no es de ninguna manera está garantizado a ser completa o libre de errores

class listview (object): 
    def __init__(self, data, start, end): 
     self.data = data 
     self.start, self.end = start, end 
    def __repr__(self): 
     return "<%s %s>" % (type(self).__name__, list(self)) 
    def __len__(self): 
     return self.end - self.start 
    def __getitem__(self, idx): 
     if isinstance(idx, slice): 
      return [self[i] for i in xrange(*idx.indices(len(self)))] 
     if idx >= len(self): 
      raise IndexError 
     idx %= len(self) 
     return self.data[self.start+idx] 
    def __setitem__(self, idx, val): 
     if isinstance(idx, slice): 
      start, stop, stride = idx.indices(len(self)) 
      for i, v in zip(xrange(start, stop, stride), val): 
       self[i] = v 
      return 
     if idx >= len(self): 
      raise IndexError(idx) 
     idx %= len(self) 
     self.data[self.start+idx] = val 


L = range(10) 

s = listview(L, 2, 5) 

print L 
print s 
print len(s) 
s[:] = range(3) 
print s[:] 
print L 

Salida:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
<listview [2, 3, 4]> 
3 
[0, 1, 2] 
[0, 1, 0, 1, 2, 5, 6, 7, 8, 9] 

Es posible asignar a los índices en la vista de lista, y se reflexionar sobre la lista subyacente. Sin embargo, no tiene sentido definir append o acciones similares en la vista de lista. También puede romperse si la lista subyacente cambia de longitud.

Cuestiones relacionadas