python: creando un histogtwig fuera del diccionario

Soy nuevo en Python y estoy aprendiendo a hacer las cosas de la manera correcta.

Tengo lista de diccionarios d . Cada diccionario representa a los usuarios y contiene información como user_id, age, etc. Esta lista d puede contener varios diccionarios que representan al mismo usuario (pero con información ligeramente diferente que no importa para mis propósitos). Quiero crear un histogtwig que muestre cuántos usuarios hay en d con una edad determinada. ¿Cómo hacerlo de manera eficiente?

Edición: quiero enfatizar que necesito eliminar duplicados en la lista.

Bueno, el enfoque clásico de este problema sería crear un punto de partida predeterminado:

 import collections histogram = collections.defaultdict(int) 

Luego itere sobre los diccionarios en la lista, y (usando d_list lugar de d como el nombre de la lista de diccionarios),

 for d in d_list: histogram[d['age']] += 1 

Pero incluiste información adicional que me confunde. Dijiste que múltiples dictados podrían representar al mismo usuario. ¿Quieres eliminar esos duplicados del histogtwig? Si esa es su pregunta, un enfoque sería almacenar a los usuarios en un user_records de user_records de user_records usando user_records (firstname, lastname) como claves. Luego, los diccionarios sucesivos que representan al mismo usuario se estrellarían entre sí y solo se conservaría un registro por usuario. Luego itere sobre los valores en ese diccionario (tal vez usando user_records.itervalues() ).

Este enfoque general puede modificarse para usar los valores de cada registro que mejor identifiquen a los usuarios únicos. Si el valor user_id es único por usuario, entonces use esa como la clave en lugar de (firstname, lastname) . Pero su pregunta sugirió (para mí) que user_id no sería necesariamente el mismo para dos usuarios que son iguales.

Sin embargo, una vez que hayas eliminado los duplicados, también hay un atajo si estás usando Python> = 2.7:

 histogram = collections.Counter(d['age'] for d in user_records.itervalues()) 

Algún código de ejemplo … digamos que tenemos un record_list :

 >>> record_list [{'lastname': 'Mann', 'age': 23, 'firstname': 'Joe'}, {'lastname': 'Moore', 'age': 23, 'firstname': 'Alex'}, {'lastname': 'Sault', 'age': 33, 'firstname': 'Marie'}, {'lastname': 'Mann', 'age': 23, 'firstname': 'Joe'}] >>> user_ages = dict(((d['firstname'], d['lastname']), d['age']) for d in record_list) >>> user_ages {('Joe', 'Mann'): 23, ('Alex', 'Moore'): 23, ('Marie', 'Sault'): 33} 

Como puede ver, el record_list tiene un duplicado, pero el user_ages no lo tiene. Ahora obtener un recuento de las edades es tan simple como ejecutar los valores a través de un Counter .

 >>> collections.Counter(user_ages.itervalues()) Counter({23: 2, 33: 1}) 

Lo mismo se puede hacer con cualquier cadena u objeto inmutable que pueda servir como un identificador único de un usuario en particular.

Podría usar itertools.groupby para agrupar en listas todos los diccionarios que tienen la misma edad y, después de eso, simplemente calcular la longitud de esas listas.

Por ejemplo:

 import itertools l = [{'user_id': 1, 'age': 20}, {'user_id': 2, 'age': 21}, {'user_id': 3, 'age': 21}, {'user_id': 4, 'age': 20}, {'user_id': 5, 'age': 21}, {'user_id': 6, 'age': 21}, ] def get_age(d): return d.get('age') print [(age, len(list(group))) for age, group in itertools.groupby(sorted(l, key=get_age), key=get_age)] 

Ejemplo de salida:

 [(20, 2), (21, 5)] 

Nota: Como lo señaló @Dougal, la lista debe estar sorted . De itertools.groupby contrario, itertools.groupby no funcionará como se espera.

Tratando de mejorar la respuesta de @ senderle, espero que haya entendido mejor el problema.

Supongo que la lista contiene diccionarios, donde las claves son ID de usuario y los datos son objetos que tienen la propiedad age :

 import collections # Merge all dictionaries to one uid->age mapping (I'm sure there's a shorter way) all_ages={} for d1 in d: for uid,data in d1.iteritems(): all_ages[uid]=data.age # Count distinct users per age histogram = collections.defaultdict(int) for uid,age in all_ages.iteritems(): histogram[age]+=1