Estoy pasando por un montón de tuplas con una correlación de muchos a muchos, y quiero hacer un diccionario donde cada b de (a, b) tenga una lista de todas las a que correspondan a una b. Parece incómodo probar una lista en la clave b en el diccionario, luego buscar una a, luego agregar una si no está allí, cada vez a través del ciclo de digestión de la tupla; pero no he encontrado una mejor manera todavía. ¿Existe uno? ¿Hay alguna otra forma de hacer esto que sea mucho más bonita?¿Existe una manera eficiente de crear una lista o anexarla si ya existe?
Respuesta
Ver the docs para el método setdefault()
:
setdefault (tecla [, por defecto])
Si la clave es en el diccionario, devolver su valor. De lo contrario, inserte la clave con un valor de predeterminado y devuelva el valor predeterminado. el valor predeterminado está predeterminado en Ninguno.
Usted puede utilizar esto como una única llamada que hará que b si existe, o la serie B a una lista vacía si no existe - y de cualquier manera, el retorno b:
>>> key = 'b'
>>> val = 'a'
>>> print d
{}
>>> d.setdefault(key, []).append(val)
>>> print d
{'b': ['a']}
>>> d.setdefault(key, []).append('zee')
>>> print d
{'b': ['a', 'zee']}
Combine esto con un simple "no en" comprobar y que ha hecho lo que está buscando en tres líneas:
>>> b = d.setdefault('b', [])
>>> if val not in b:
... b.append(val)
...
>>> print d
{'b': ['a', 'zee', 'c']}
'defaultdict' es un poco mejor que' setdefault', suponiendo que tiene Python 2.5 o superior. – ephemient
Estoy atrapado con 2.34, así que esta es en realidad la respuesta, para mí, ¡gracias, James! – user249228
D'oh. 'set()' es bueno, pero no está incorporado hasta 2.4. ¿Por qué tu Python es tan viejo? :-( – ephemient
puede ordenar su tuplas O (n log n) a continuación, crear su propio diccionario O (n)
o simplier O (n), pero podría imponer una carga pesada sobre la memoria en caso de muchas tuplas:
your_dict = {}
for (a,b) in your_list:
if b in your_dict:
your_dict[b].append(a)
else:
your_dict[b]=[a]
Hmm es más o menos lo mismo que usted ha descrito. ¿Qué tiene de incómodo?
También podría considerar el uso de una base de datos sql para hacer el trabajo sucio.
El método más simple es O (n), por cierto, por lo que es preferible ordenar el método de tuplas. – kennytm
sí, también lo indiqué en la versión editada. –
algún comentario sobre downvoting? –
No estoy seguro de cómo va a salir de la prueba clave, pero una vez que par clave/valor se ha inicializado es fácil :)
d = {}
if 'b' not in d:
d['b'] = set()
d['b'].add('a')
El conjunto se asegurará de que sólo 1 de 'una 'está en la colección. Sin embargo, debe hacer la comprobación inicial 'b' para asegurarse de que exista la clave/valor.
curiosidad por qué -1? ¿Está esto mal de alguna manera? Eliminaré la respuesta si está mal. –
Suponiendo que en realidad no estás atado a las listas, y defaultdictset son bastante práctico.
import collections
d = collections.defaultdict(set)
for a, b in mappings:
d[b].add(a)
Si realmente desea listas en lugar de conjuntos, se puede seguir esto con un
for k, v in d.iteritems():
d[k] = list(v)
Y si realmente desea un diccionario en lugar de un defaultdict, se puede decir
d = dict(d)
Aunque no veo ninguna razón por la que lo desee.
ah sí, esto pasa por la comprobación inicial sin ningún valor. Gracias! Aprendí algo nuevo. :) –
+1 por 'defaultdict', porque realmente es la solución más Pythonic. – jathanism
También me gustó cómo [este tipo me ayudó a encontrar el default (lambda: defaultdict (list))] (http://ohuiginn.net/mt/2010/07/nested_dictionaries_in_python.html) – lkraav
Usar colecciones.defaultdict
your_dict = defaultdict(list)
for (a,b) in your_list:
your_dict[b].append(a)
lugar de utilizar un if
, que yo sepa, es más Pythonic utilizar un bloque try
lugar.
your_list=[('a',1),('a',3),('b',1),('f',1),('a',2),('z',1)]
your_dict={}
for (a,b) in your_list:
try:
your_dict[b].append(a)
except KeyError:
your_dict[b]=[a]
print your_dict
Dict get
method? Devuelve el valor de my_dict[some_key]
si some_key
está en el diccionario, y si no - devuelve algún valor por defecto ([]
en el ejemplo siguiente):
my_dict[some_key] = my_dict.get(some_key, []).append(something_else)
Hay otra manera que sea más eficiente (aunque quizás no tan eficiente como conjuntos) y simple. Es similar en la práctica al defaultdict
pero no requiere una importación adicional. Dado que tienes un dict con teclas vacías (None), significa que también creas las claves dict en algún lado. Puede hacerlo con el método dict.fromkeys
, y este método también permite establecer un valor predeterminado para todas las teclas.
keylist = ['key1', 'key2']
result = dict.fromkeys(keylist, [])
donde result
habrá: { 'key1': [], 'clave2': []}
entonces usted puede hacer su bucle y utilizar result['key1'].append(..)
directamente
- 1. Crear una cookie si (y sólo si) no existe ya
- 2. cómo comprobar si el objeto ya existe en una lista
- 3. Cómo crear una lista de números y anexarla inversamente de manera eficiente en Ruby
- 4. ¿Cómo elimino una función si ya existe?
- 5. Crear si no existe
- 6. Crear una carpeta si no existe
- 7. Crear tabla en SQLite solo si ya no existe
- 8. Compruebe si existe una inclusión (o requiere)
- 9. Comprobando si existe una URL o no
- 10. ¿Existe una implementación eficiente de tetration?
- 11. ¿Existe alguna manera más rápida de verificar si existe una página web externa?
- 12. ¿Cómo INSERTAR un registro o ACTUALIZAR si ya existe?
- 13. Pruebe si existe un índice de una lista
- 14. Cómo encontrar si existe una carpeta en la Bandeja de entrada y crear si no existe
- 15. Mimic File.Move si el destino ya existe
- 16. Averiguar si existe una variable
- 17. NSMutableArray compruebe si el objeto ya existe
- 18. SQL portátil para determinar si existe una tabla o no?
- 19. Comprobar si un evento ya existe
- 20. ¿Existe una manera eficiente de eliminar cada vista/función/tabla/sp de una base de datos?
- 21. cheque si el valor ya existe
- 22. ¿Existe una implementación conocida de una lista vinculada indexada?
- 23. Comprobando si existe un valor en una lista Redis
- 24. ¿Existe alguna manera fácil de aleatorizar una lista en VB.NET?
- 25. ¿Cómo comprobar si existe una ventana hija?
- 26. Compruebe si existe una base de datos antes de crear
- 27. ¿Es más eficiente ejecutar siempre una consulta de eliminación o verificar si existe esa información primero?
- 28. ¿Cómo puedo probar si existe una lista de archivos?
- 29. ¿Existe alguna manera más segura de crear un directorio si no existe?
- 30. Crear si una entrada no existe, de lo contrario ¿actualizar?
por más bonito que quiere decir sintácticamente o algorítmicamente? –