【问题标题】:How do I extract part of a tuple that's duplicate as key to a dictionary, and have the second part of the tuple as value?如何提取作为字典键重复的元组的一部分,并将元组的第二部分作为值?
【发布时间】:2016-09-21 17:17:46
【问题描述】:

我对 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), (35538​​5,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) , (35538​​5,6.68906e+06)], 5L: [(355261,6.68905e+06), (355364,6.6891e+06)], 6L: [(355364,6.6891e+06), (355481,6.68916e +06)], 7L: [(35538​​5,6.68906e+06), (355501,6.68912e+06)]}

如您所见,许多行都有一个共同的端点:(35538​​5,6.68906e+06) 例如由 7L、4L 和 0L 共享。

我想创建一个新字典,获取共享点作为键,并将第二个点作为值。

例如:{(35538​​5,6.68906e+06):[(355277,6.68901e+06), (355364,6.6891e+06), (355501,6.68912e+06)]}

我一直在查看列表理解教程,但没有取得多大成功:大多数人都希望删除重复项,而我希望将它们用作键(具有唯一 ID)。我认为 set() 仍然有用吗?

如果有任何帮助,我将不胜感激,在此先感谢。

【问题讨论】:

标签: python-2.7 dictionary duplicates qgis


【解决方案1】:

也许这就是你需要的?

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] 是什么意思,代码的哪一部分规定了要附加到当前键的值?
  • 实际上我使用的是您的旧代码,您的编辑使事情变得更好:现在正确的键附加到正确的值,但每个键应该附加多个值;使用这个 sn-p 它只更新其中一个。
  • 也许你可以这样试试?很抱歉,在之前的版本中我错误地输入了“difference”而不是“intersection”
  • 好的很好(感谢#)所以现在我们在一个列表中有两个正确的值。但它仍然缺少一些价值。事实上(也许我应该把它放在正文中)每个 key_point 至少有三个 value_point,这意味着很可能有五个或六个(我们正在处理街道交叉口)。例如,值 355364 由 3L、4L、5L 和 6L 共享,但 35538​​5 仅由 0L、7L、4L 共享。
  • 我认为现在它可以有尽可能多的值,并且在我的测试中它是准确的,4个值,3个值和3个值。
【解决方案2】:

查看此代码:

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

【讨论】:

  • 您好,感谢您的回复。打印 b 时,我得到值 355277,它不应该是键的一部分。也许是因为它是第一个迭代的术语?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 2021-12-09
  • 1970-01-01
  • 2019-03-28
  • 2012-02-20
  • 1970-01-01
相关资源
最近更新 更多