2010-08-11 2 views
1

У меня есть список словарей. в списке есть несколько точек, некоторые из них несколько. Когда есть множественная запись, я хочу рассчитать среднее значение x и y этой точки. Моя проблема в том, что я не знаю, как прокрутить список словарей, чтобы сравнить идентификаторы точек!цикл через список словарей

, когда я использовать что-то вроде этого:

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

К сожалению, верстка немного сложнее ... второй цикл внутри первой ... я думаю, что он сравнивает первую запись из список, так что это одно и то же ... так что мне нужно начинать во втором цикле со второй записи, но я не могу сделать это с i-1, потому что я - словарь с отверстиями ... Кто-то идея? Заранее благодарю!

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 

нормально, я думаю, что ... на данный момент тот более запутанным:) ...

+0

Какой язык вы используете? – Jonn

+0

Я использую python – aleho

+0

Что должно произойти, если три или более элемента имеют один и тот же '' id''? Вы хотите рассчитать среднее значение для каждой пары элементов? Или вы хотите сгруппировать все элементы с одним и тем же «id» и взять среднее значение кластера? – unutbu

ответ

4

Один из способов будет изменить способ хранения ваших очков, потому что, как вы уже заметили, что трудно получить то, что вы хотите от него.

Гораздо более полезным структура будет ДИКТ где id карты к списку пунктов:

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

Я отложил комментарий, который был в середине написания, поскольку THC4k верен. Список dicts не идеален вообще - более естественно, у вас есть ONE dict, в котором вы можете сначала дедуплицировать очки. +1 Однако, THC4k, было бы неплохо, если бы вы добавили код о том, как построить такой dict из списка, чтобы сделать его более понятным для OP. – chryss

+0

Итак, когда я иду с point_dict [id] .append (...), я получаю словарь с несколькими элементами с разными идентификаторами и геометрией ?! Я хотел сделать это со списком словарей, потому что я не мог найти ничего для хранения нескольких элементов (например, в таблице excel) в словаре ... – aleho

+2

уведомление 'defaultdict (list)' использует встроенный 'list' поэтому вы не должны ** использовать 'list' для имени переменной –

0

Я не совсем уверен, что вы хотите сделать, но я думаю, что фильтрация списка поможет вам , Существует встроенная функция filter, которая выполняет итерацию по последовательности, и для каждого элемента он вызывает пользовательскую функцию, чтобы определить, включать ли этот элемент в результирующий список или нет.

Например:

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] 

Таким образом, имея список словарей, чтобы отфильтровать все словари с определенной записи, равной заданному значению, вы могли бы сделать что-то вроде этого:

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) 

С помощью этой функции, чтобы получить все словари со знаком «id», равным 2, вы можете сделать:

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

При этом, ваш основной цикл может выглядеть следующим образом:

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 

Я надеюсь, что я правильно вас понял, и что это полезно для вас.

+0

oh great !!! спасибо много ... это хорошо выглядит ... я должен прочитать его снова и попробовать с моим! – aleho

+0

он работает! Jipie! – aleho

Смежные вопросы