creando una lista predeterminada en python

Estoy tratando de crear una lista equivalente para la muy útilcollections.defaultdict. El siguiente diseño funciona muy bien:

class defaultlist(list):
    def __init__(self, fx):
        self._fx = fx
    def __setitem__(self, index, value):
        while len(self) <= index:
            self.append(self._fx())
        list.__setitem__(self, index, value)

Así es como lo usa:

>>> dl = defaultlist(lambda:'A')
>>> dl[2]='B'
>>> dl[4]='C'
>>> dl
['A', 'A', 'B', 'A', 'C']

¿Qué debo agregar a la lista predeterminada para admitir el siguiente comportamiento?

>>> dl = defaultlist(dict)
>>> dl[2]['a'] = 1
>>> dl
[{}, {}, {'a':1}]
 Jonathan05 ene. 2012 21:47
Esta pregunta es un seguimiento deést
 user39576005 ene. 2012 21:54
¿Asumo que solo está buscando el método para sobrecargar el acceso al elemento (en lugar de la asignación del elemento)?
 FakeRainBrigand05 ene. 2012 21:57
Nodl[2] = {'a', 1} tiene más sentido @

Respuestas a la pregunta(4)

Solución de preguntas

En el ejemplo que da, primero intenta recuperar un valor no existente en la lista, como lo hacedl[2]['a'], Python primero recupera el tercer elemento (índice 2) de la lista, luego procede a obtener el elemento llamado 'a' en ese objeto; por lo tanto, debe implementar su comportamiento de extensión automática en la__getitem__ método también, así:

class defaultlist(list):
    def __init__(self, fx):
        self._fx = fx
    def _fill(self, index):
        while len(self) <= index:
            self.append(self._fx())
    def __setitem__(self, index, value):
        self._fill(index)
        list.__setitem__(self, index, value)
    def __getitem__(self, index):
        self._fill(index)
        return list.__getitem__(self, index)

Hay un paquete de Python disponible:

$ pip install defaultlist

Las indicaciones agregadas se completan con Ninguno de forma predeterminada.

>>> from defaultlist import defaultlist
>>> l = defaultlist()
>>> l
[]
>>> l[2] = "C"
>>> l
[None, None, 'C']
>>> l[4]
>>> l
[None, None, 'C', None, None]

Slices e indicios negativos también son compatibles

>>> l[1:4]
[None, 'C', None]
>>> l[-3]
'C'

as funciones de fábrica simples se pueden crear a través de lambd

>>> l = defaultlist(lambda: 'empty')
>>> l[2] = "C"
>>> l[4]
'empty'
>>> l
['empty', 'empty', 'C', 'empty', 'empty']

También es posible implementar funciones avanzadas de fábrica:

>>> def inc():
...     inc.counter += 1
...     return inc.counter
>>> inc.counter = -1
>>> l = defaultlist(inc)
>>> l[2] = "C"
>>> l
[0, 1, 'C']
>>> l[4]
4
>>> l
[0, 1, 'C', 3, 4]

Ver elDocumentació para más detalles.

Su respuesta a la pregunta