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

How can I prevent adding the same value (With another key) into a dictionary?

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

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. """

这是问题所在:

'Rik' 表示与 '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

但问题依然存在。

当我 "print d" 我得到 R12 和 R21(每对数字“ i k ”也是如此)。

我能做什么?

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

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

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

您可以使用以下内容:

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) 的距离分配给字典。

我使用d[i, k]而不是d['R' + str(i) + str(k)],因为后者有以下缺点:我们无法推断,例如,如果d['R123']指的是(12, 3)(1, 23).

此外,我将字典初始化 (d = {}) 移到了两个循环之外,因为它是为每个 i.

初始化的

如果我没理解错的话,你正在寻找两个元素的所有组合。您可以使用 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)}

或者,要对 ik 的每个值进行一次(可能很昂贵的)Vector([SomeCoordinates]) 计算,试试这个(感谢 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) 代替。