我需要用下一个代码给出的对键值填充字典:
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;)。
我该怎么办?
答案 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
(我假设你的脚本只需要距离值,而不是当前键的信息。)