2010-08-11 5 views
1

J'ai une liste de dictionnaires. il y a plusieurs points dans la liste, certains sont multiples. Quand il y a une entrée multiple, je veux calculer la moyenne des x et des y de ce point. Mon problème est, que je ne sais pas comment parcourir la liste des dictionnaires pour comparer les ID des points!parcourir la liste des dictionnaires

quand j'utiliser quelque chose comme ça:

for i in list: 
    for j in list: 
    if i['id'] == j['id']: 
     point = getPoint(i['geom']) 
     .... 

désolé, le formattage est un peu délicat ... la deuxième boucle est dans la première ... je pense qu'il compare la première entrée la liste, donc c'est la même chose ... donc je dois commencer dans la deuxième boucle avec la deuxième entrée, mais je ne peux pas le faire avec i-1 parce que je suis le dictionnaire des trous ... Quelqu'un une idée? merci d'avance!

for j in range(1, len(NEWPoint)): 
     if i['gid']==j['gid']: 
     allsamePoints.append(j) 
     for k in allsamePoints: 
     for l in range(1, len(allsamePoints)): 
      if k['gid']==l['gid']: 
       Point1 = k['geom'] 
       Point2=l['geom'] 
       X=(Point1.x()+Point2.x())/2 
       Y=(Point1.y()+Point2.y())/2 
       AVPoint = QgsPoint(X, Y) 
       NEWReturnList.append({'gid': j['gid'], 'geom': AVPoint}) 
       del l 
     for m in NEWReturnList: 
      for n in range(1, len(NEWReturnList)): 
       if m['gid']==n['gid']: 
       Point1 = m['geom'] 
       Point2=n['geom'] 
       X=(Point1.x()+Point2.x())/2 
       Y=(Point1.y()+Point2.y())/2 
       AVPoint = QgsPoint(X, Y) 
       NEWReturnList.append({'gid': j['gid'], 'geom': AVPoint}) 
       del n 
       else: 
       pass 

ok, je pense ... au moment des thats plus confus:) ...

+0

Quelle langue utilisez-vous? – Jonn

+0

J'utilise python – aleho

+0

Que se passe-t-il si trois éléments ou plus ont le même «id»? Voulez-vous calculer la moyenne de chaque paire d'éléments? Ou voulez-vous regrouper tous les éléments avec le même «id» et prendre la moyenne du cluster? – unutbu

Répondre

4

Une façon serait en train de changer la façon dont vous stockez vos points, parce que vous avez déjà remarqué, il est difficile de obtenir ce que vous voulez en sortir.

Une structure beaucoup plus utile serait un dict où les id cartes à une liste de points:

from collections import defaultdict 
points_dict = defaultdict(list) 

# make the new dict 
for point in point_list: 
    id = point["id"] 
    points_dict[id].append(point['geom']) 

def avg(lst): 
    """ average of a `lst` """ 
    return 1.0 * sum(lst)/len(lst) 

# now its simple to get the average 
for id in points_dict: 
    print id, avg(points_dict[id]) 
+0

Je me suis rétracté le commentaire que j'étais en train d'écrire car THC4k est correct. Une liste de dictionnaires n'est pas idéale du tout - plus naturellement, vous avez UNE dict dans laquelle vous pouvez dédupliquer les points en premier. +1 Cependant, THC4k, ce serait bien si vous avez ajouté du code sur la façon de construire une telle dict de la liste, pour le rendre plus clair pour l'OP. – chryss

+0

donc, quand je vais avec le points_dict [id] .append (...) je reçois un dictionnaire avec plusieurs éléments avec des id et des géométries différentes ?! Je voulais faire cela avec la liste des dictionnaires, parce que je ne trouvais rien pour stocker plusieurs éléments (comme dans une table excel) dans un dictionnaire ... – aleho

+2

notice 'defaultdict (list)' utilise la 'list' intégrée c'est pourquoi vous ne devriez jamais utiliser 'list' pour un nom de variable ** –

0

Je ne suis pas tout à fait sûr de ce que vous voulez faire, mais je pense que le filtrage de liste pourrait vous aider . Il ya la fonction intégrée filter, qui itère sur une séquence et pour chaque élément, elle appelle la fonction définie par l'utilisateur pour déterminer s'il faut ou non inclure cet élément dans la liste résultante.

Par exemple:

def is4(number): 
    return number == 4 

l = [1, 2, 3, 4, 5, 6, 4, 7, 8, 4, 4] 
filter(is4, l) # returns [4, 4, 4, 4] 

Ainsi, ayant une liste de dictionnaires, de filtrer tous les dictionnaires avec entrée particulière égale à une valeur donnée, vous pouvez faire quelque chose comme ceci:

def filter_dicts(dicts, entry, value): 
    def filter_function(d): 
     if entry not in d: 
     return False 
     return d[entry] == value 
    return filter(filter_function, dicts) 

Avec cette fonction, pour obtenir tous les dictionnaires avec l'entrée "id" égale à 2, vous pouvez faire:

result = filter_dicts(your_list, "id", 2) 

Avec cela, votre boucle principale pourrait ressembler à ceci:

processed_ids = set() 
for item in list: 
    id = item['id'] 
    if id in processed_ids: 
     continue 
    processed_ids.add(id) 
    same_ids = filter_dicts(list, "id", id) 
    # now do something with same_ids 

J'espère que je vous ai bien compris et que cela est utile pour vous.

+0

oh génial !!! merci beaucoup ... ça a l'air bien ... je dois le relire et l'essayer avec le mien! – aleho

+0

ça marche! Jipie! – aleho

Questions connexes