La lista de Python establece el valor en el índice si el índice no existe

¿Hay alguna forma, lib o algo en python que pueda establecer valor en la lista en un índice que no existe? Algo así como la creación del índice de tiempo de ejecución en la lista:

l = [] l[3] = 'foo' # [None, None, None, 'foo'] 

Y más aún, con listas multidimensionales:

 l = [] l[0][2] = 'bar' # [[None, None, 'bar']] 

O con uno existente:

 l = [['xx']] l[0][1] = 'yy' # [['xx', 'yy']] 

No hay una incorporada, pero es bastante fácil de implementar:

 class FillList(list): def __setitem__(self, index, value): try: super().__setitem__(index, value) except IndexError: for _ in range(index-len(self)+1): self.append(None) super().__setitem__(index, value) 

O, si necesita cambiar las listas de vainilla existentes:

 def set_list(l, i, v): try: l[i] = v except IndexError: for _ in range(i-len(l)+1): l.append(None) l[i] = v 

No se puede crear una lista con huecos. Podrías usar un dict o este hombrecito rápido:

 def set_list(i,v): l = [] x = 0 while x < i: l.append(None) x += 1 l.append(v) return l print set_list(3, 'foo') >>> [None, None, None, 'foo'] 

Si realmente desea la syntax en su pregunta, defaultdict es probablemente la mejor manera de obtenerla:

 from collections import defaultdict def rec_dd(): return defaultdict(rec_dd) l = rec_dd() l[3] = 'foo' print l {3: 'foo'} l = rec_dd() l[0][2] = 'xx' l[1][0] = 'yy' print l  

No es exactamente una 'lista de listas', pero funciona más o menos como una.

Sin embargo, realmente necesita especificar el caso de uso ... lo anterior tiene algunas ventajas (puede acceder a los índices sin verificar si existen primero), y algunas desventajas, por ejemplo, l[2] en un dict normal devolverá un KeyError , pero en defaultdict solo crea un defaultdict blanco, lo agrega y luego lo devuelve.

Otras implementaciones posibles para soportar diferentes azúcares sintácticos podrían involucrar clases personalizadas, etc., y tendrán otras ventajas y desventajas.

No es infalible, pero parece que la forma más fácil de hacerlo es inicializar una lista mucho más grande de lo que necesita, es decir

 l = [None for i in some_large_number] l[3] = 'foo' # [None, None, None, 'foo', None, None None ... ]