2010-05-05 4 views
1

Voici mon problème: J'ai une liste de dictionnaires Python de forme identique, qui sont destinés à représenter les lignes d'une table dans une base de données , quelque chose comme ceci:Implémentation de "select distinct ... from ..." sur une liste de dictionnaires Python

[ {'ID': 1, 
    'NAME': 'Joe', 
    'CLASS': '8th', 
    ... }, 
    {'ID': 1, 
    'NAME': 'Joe', 
    'CLASS': '11th', 
    ... }, 
    ...] 

Je l'ai déjà écrit une fonction pour obtenir les valeurs uniques pour un domaine particulier dans cette liste des dictionnaires, qui était trivial. Cette fonction met en œuvre quelque chose comme:

select distinct NAME from ...

Cependant, je veux être en mesure d'obtenir la liste des champs multiples uniques, semblables à:

select distinct NAME, CLASS from ...

qui je trouve être non -banal. Existe-t-il un algorithme ou une fonction incluse dans Python pour m'aider avec ce problème? Avant de suggérer de charger les fichiers CSV dans une table SQLite ou quelque chose de similaire, ce n'est pas une option pour l'environnement dans lequel je suis, et croyez-moi, c'était ma première pensée.

+0

Voulez-vous toutes les paires uniques, ou tous les noms uniques, puis les classes uniques, séparément? – Claudiu

+0

si vous pouvez le faire avec un champ quel est le problème de le faire avec deux ou plus ?. – joaquin

+0

@Claudiu Je veux les paires uniques. Si je les voulais séparément, je pourrais simplement appeler la fonction deux fois. Le faire avec un ou deux noms de champs n'est pas un problème, c'est généraliser au nombre N de champs. – daveslab

Répondre

9

Si vous voulez comme un générateur:

def select_distinct(dictionaries, keys): 
    seen = set() 
    for d in dictionaries: 
    v = tuple(d[k] for k in keys) 
    if v in seen: continue 
    yield v 
    seen.add(v) 

si vous voulez que le résultat sous une autre forme (par exemple, une liste au lieu d'un générateur), il est pas difficile de modifier ce (par exemple, .append au liste de résultats initialement vide au lieu de yield ing, et renvoie la liste des résultats à la fin).

à appeler, bien sûr, comme

for values_tuple in select_distinct(thedicts, ('NAME', 'CLASS')): 
    ... 

ou similaires.

0

distinct_list = liste (ensemble ([(d [ 'name'], d [ 'CLASS']) pour d en row_list]))

où row_list la liste des dicts que vous avez

0

On peut mettre en œuvre la tâche en utilisant le hachage. Juste hacher le contenu des lignes qui apparaissent dans la requête distincte et ignorer celles avec le même hachage.

Questions connexes