如何防止将相同的值(使用另一个键)添加到字典中?

时间:2015-04-11 21:13:00

标签: python dictionary nested-loops

我需要用下一个代码给出的对键值填充字典:

for i in range(1,n+1):
    d = {}
    Ri = Vector([#SomeCoordinates])

    for k in range(1,n+1):
        Rk = Vector([#SomeCoordinates])

        if i != k:
            d['R'+str(i)+str(k)] = (Rk-Ri).mod  # Distance between Ri and Rk
        else:
            None

""" Since  (Rk-Ri).mod  gives me the distance between two points (i and k),     
it's meaningless to calc the distance if i == k. """

问题在于:

'里克'代表与Rki'相同的距离。而且我不想两次增加距离。

然后,我尝试使用此代码:

        if i != k and ( ('R'+str(i)+str(k)) and ('R'+str(k)+str(i)) ) not in d:
            d['R'+str(i)+str(k)] = (Rk-Ri).mod
        else:
            None

但问题仍然存在。

当我"打印d"我得到R12但也有R21(和每对数字一样#34;我和#34;)。

我该怎么办?

3 个答案:

答案 0 :(得分:3)

您可以使用以下内容:

d = {}
for i in range(1, n + 1):
    Ri = Vector([#SomeCoordinates]).
    for k in range(i + 1, n + 1):
        Rk = Vector([#SomeCoordinates])
        d[i, k] = d[k, i] = (Rk - Ri).mod 

这样我们确保我们只选择一对(通过强制执行k > i),然后我们就可以为字典分配(i, k)(k, i)的距离。< / p>

我使用d[i, k]代替d['R' + str(i) + str(k)],因为后者有以下缺点:例如,如果d['R123']引用(12, 3)或{{}},我们无法推断{1}}。

另外,我在两个循环之外移动了字典初始化((1, 23)),因为它是为每个d = {}初始化的。

答案 1 :(得分:2)

如果我认真对待你,你正在寻找两个元素的所有组合。您可以使用itertools.combinations自动生成所有此类组合而不会重复。

d = {}
for i, k in itertools.combinations(range(1, n+1), 2):
    Ri = Vector([SomeCoordinates])
    Rk = Vector([SomeCoordinates])
    d['R'+str(i)+str(k)] = (Rk-Ri).mod

你甚至可以使它成为一个词典理解(虽然它可能有点长):

d = {'R'+str(i)+str(k)] : (Vector([SomeCoordinates]) - Vector([SomeCoordinates])).mod 
     for i, k in itertools.combinations(range(1, n+1), 2)}

或者,为Vector([SomeCoordinates])i的每个值执行k一次(可能是昂贵的)计算,请尝试此操作(感谢 JuniorCompressor 指出这一点):

R = {i: Vector([SomeCoordinates]) for i in range(1, n+1)}
d = {(i, k): (R[i] - R[k]).mod for i, k in itertools.combinations(range(1, n+1), 2)}

另外,正如其他人所指出的那样,'R'+str(i)+str(k)并不是一个好的关键,因为它不可能在(1,23)(12,3),最终都是'R123'。我建议您只使用元组(i,k)

答案 2 :(得分:0)

您可能始终将较小的值放在第一位,以便自动覆盖之前的条目:

if i != k:
    key = str(i) + "," + str(k) if i < k else str(k) + "," + str(i)
    d['R'+key] = (Rk-Ri).mod

(我假设你的脚本只需要距离值,而不是当前键的信息。)