dictionary diccionarios - Python creando un diccionario de listas.





dentro agregar (6)


Personalmente, solo uso JSON para convertir cosas en cadenas y viceversa. Cuerdas entiendo

import json
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
mydict = {}
hash = json.dumps(s)
mydict[hash] = "whatever"
print mydict
#{'[["yellow", 1], ["blue", 2], ["yellow", 3], ["blue", 4], ["red", 1]]': 'whatever'}

Quiero crear un diccionario cuyos valores sean listas. Por ejemplo:

{
  1: ['1'],
  2: ['1','2'],
  3: ['2']
}

Si lo hago:

d = dict()
a = ['1', '2']
for i in a:
    for j in range(int(i), int(i) + 2): 
        d[j].append(i)

Obtengo un KeyError, porque d [...] no es una lista. En este caso, puedo agregar el siguiente código después de la asignación de un para inicializar el diccionario.

for x in range(1, 4):
    d[x] = list()

¿Hay una mejor manera de hacer esto? Digamos que no sé las claves que voy a necesitar hasta que esté en el segundo bucle for . Por ejemplo:

class relation:
    scope_list = list()
...
d = dict()
for relation in relation_list:
    for scope_item in relation.scope_list:
        d[scope_item].append(relation)

Una alternativa sería entonces reemplazar

d[scope_item].append(relation)

con

if d.has_key(scope_item):
    d[scope_item].append(relation)
else:
    d[scope_item] = [relation,]

¿Cuál es la mejor manera de manejar esto? Idealmente, añadir sería "simplemente funciona". ¿Hay alguna manera de expresar que quiero un diccionario de listas vacías, incluso si no conozco todas las claves cuando creo la lista por primera vez?




Su pregunta ya ha sido respondida, pero IIRC puede reemplazar líneas como:

if d.has_key(scope_item):

con:

if scope_item in d:

Es decir, d referencia a d.keys() en esa construcción. A veces, defaultdict no es la mejor opción (por ejemplo, si desea ejecutar varias líneas de código después de la else asociada con lo anterior), y encuentro la sintaxis más fácil de leer.




Utilice setdefault :

d = dict()
a = ['1', '2']
for i in a:
    for j in range(int(i), int(i) + 2): 
        d.setdefault(j, []).append(i)

print d  # prints {1: ['1'], 2: ['1', '2'], 3: ['2']}

La función setdefault nombre bastante extraño dice "Obtenga el valor con esta clave, o si esa clave no está allí, agregue este valor y luego devuélvalo".

Edit : Como otros han señalado correctamente, defaultdict es una opción mejor y más moderna. setdefault sigue siendo útil en versiones anteriores de Python (antes de la versión 2.5).




Puedes construirlo con una lista de comprensión como esta:

>>> dict((i, range(int(i), int(i) + 2)) for i in ['1', '2'])
{'1': [1, 2], '2': [2, 3]}

Y para la segunda parte de tu pregunta usa defaultdict

>>> from collections import defaultdict
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
        d[k].append(v)

>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]



Puedes usar defaultdict :

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for i in a:
...   for j in range(int(i), int(i) + 2):
...     d[j].append(i)
...
>>> d
defaultdict(<type 'list'>, {1: ['1'], 2: ['1', '2'], 3: ['2']})
>>> d.items()
[(1, ['1']), (2, ['1', '2']), (3, ['2'])]



ACTUALIZACIÓN: 5 DE DICIEMBRE DE 2015 con Python 3.5

Si bien la respuesta aceptada me pareció útil, también me sorprendió que no se haya actualizado para hacer referencia a OrderedDict del módulo de colecciones de bibliotecas estándar como una alternativa viable y moderna, diseñada para resolver exactamente este tipo de problema.

from operator import itemgetter
from collections import OrderedDict

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = OrderedDict(sorted(x.items(), key=itemgetter(1)))
# OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])

La documentación oficial de OrderedDict ofrece un ejemplo muy similar, pero utilizando un lambda para la función de clasificación:

# regular unsorted dictionary
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

# dictionary sorted by value
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
# OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])




python dictionary