2016-05-24 2 views
1

Я довольно новичок в Python и Qgis, прямо сейчас я просто запускаю скрипты, но я хочу, чтобы создать плагин.Как извлечь часть кортежа, дублирующего как ключ словаря, и вторую часть кортежа как значение?

Вот часть кода у меня возникают проблемы, связанные с:

import math 

layer = qgis.utils.iface.activeLayer() 
iter = layer.getFeatures() 
dict = {} 

#iterate over features 
for feature in iter: 
    #print feature.id() 
    geom = feature.geometry() 
    coord = geom.asPolyline() 
    points=geom.asPolyline() 
#get Endpoints 
    first = points[0] 
    last = points[-1] 

#Assemble Features 
dict[feature.id() ]= [first, last] 

print dict 

Это мой результат: {0L: [(355277,6.68901e + 06), (355385,6.68906e + 06), 1L: [(355238,6,68909e + 06), (355340,6,68915e + 06)], 2L: [(355340,6,68915e + 06), (355452,6,68921e + 06)], 3L: [ (355340,6,68915e + 06), (355364,6,6891e + 06)], 4L: [(355364,6,6891e + 06), (355385,6,68906e + 06)], 5L: [(355261,6,68905e + 06), (355364,6,6891e + 06)], 6L: [(355364,6,6891e + 06), (355481,6,68916e + 06)], 7L: [(355385,6,68906e + 06), (355501, 6.68912e + 06)]}

Как вы можете видеть, многие из линий имеют общая конечная точка: (355385,6,68906e + 06) используется, например, 7L, 4L и 0L.

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

например: {(355385,6.68906e + 06): [(355277,6.68901e + 06), (355364,6.6891e + 06), (355501,6.68912e + 06)]}

Я были просмотрены учебники по пониманию списка, но без особого успеха: большинство людей хотят удалить дубликаты, тогда как я бы хотел использовать их как ключи (с уникальными идентификаторами). Правильно ли в мышлении set() все равно будет полезно?

Я был бы очень признателен за любую помощь, спасибо заранее.

+0

Re недавно удаленные вопрос: http://paste.ubuntu.com/18993669/ – Tim

ответ

0

Возможно, это то, что вам нужно?

dictionary = {} 
for i in dict: 
    for j in dict: 
     c = set(dict[i]).intersection(set(dict[j])) 
     if len(c) == 1: 
      # ok, so now we know, that exactly one tuple exists in both 
      # sets at the same time, but this one will be the key to new dictionary 
      # we need the second tuple from the set to become value for this new key 
      # so we can subtract the key-tuple from set to get the other tuple 
      d = set(dict[i]).difference(c) 
      # Now we need to get tuple back from the set 
      # by doing list(c) we get list 
      # and our tuple is the first element in the list, thus list(c)[0] 
      c = list(c)[0] 
      dictionary[c] = list(d)[0] 
     else: pass 

Этот код прикрепляет только один кортеж к ключу в словаре. Если вы хотите использовать несколько значений для каждого ключа, вы можете изменить его таким образом, что каждый ключ будет иметь список значений, это может быть сделано путем простого изменения:

# some_value cannot be a set, it can be obtained with c = list(c)[0] 
key = some_value 
dictionary.setdefault(key, []) 
dictionary[key].append(value) 

Таким образом, правильный ответ был бы:

dictionary = {} 
for i in a: 
     for j in a: 
      c = set(a[i]).intersection(set(a[j])) 
      if len(c) == 1: 
       d = set(a[i]).difference(c) 
       c = list(c)[0] 
       value = list(d)[0] 
       if c in dictionary and value not in dictionary[c]: 
        dictionary[c].append(value) 
       elif c not in dictionary: 
        dictionary.setdefault(c, []) 
        dictionary[c].append(value) 

      else: pass 
+0

Очень близко! Ваш путь действительно положил правильную точку как ключ! Спасибо! Что такое [0], а какая часть кода определяет значения, которые нужно привязать к текущему ключу? –

+0

На самом деле я использовал ваш старый код, ваше редактирование делает все лучше: теперь правильный ключ привязан к правильному значению, но каждый ключ должен иметь несколько значений; этот фрагмент обновляет только один из них. –

+0

Возможно, вы могли бы попробовать это? Мне очень жаль, в предыдущей версии я ошибочно набрал «разницу» вместо «пересечения» – Leukonoe

0

Смотреть этот код:

dict={0L: [(355277,6.68901e+06), (355385,6.68906e+06)], 1L: [(355238,6.68909e+06), (355340,6.68915e+06)], 2L: [(355340,6.68915e+06), (355452,6.68921e+06)], 3L: [(355340,6.68915e+06), (355364,6.6891e+06)], 4L: [(355364,6.6891e+06), (355385,6.68906e+06)], 5L: [(355261,6.68905e+06), (355364,6.6891e+06)], 6L: [(355364,6.6891e+06), (355481,6.68916e+06)], 7L: [(355385,6.68906e+06), (355501,6.68912e+06)]} 
dictionary = {} 
list=[] 
for item in dict : 
    list.append(dict[0]) 
    list.append(dict[1]) 

b = [] 

[b.append(x) for c in list for x in c if x not in b] 
print b # or set(b) 
res={} 

for elm in b : 
    lst=[] 
    for item in dict : 
     if dict[item][0] == elm : 
      lst.append(dict[item][1]) 
     elif dict[item][1] == elm : 
      lst.append(dict[item][0]) 
    res[elm]=lst 

print res 
+0

Привет, спасибо, что ответили. Когда printinng b, я получаю значение 355277, которое не должно быть частью ключей. Может быть, потому что это первый термин, который повторяется? –