import string
from collections import namedtuple
from collections import defaultdict
from collections import OrderedDict
matrix_col = {'11234':0, '21234':2, '31223':0, '46541':0, '83432':1, '56443':2, '63324':0, '94334':0, '72443':1}
matrix_col = OrderedDict(sorted(matrix_col.items(), key=lambda t: t[0]))
trans = defaultdict(dict)
trans['11234']['46541'] = 2
trans['11234']['21234'] = 1
trans['11234']['31223'] = 2
trans['11234']['83432'] = 1
trans['21234']['31223'] = 2
trans['21234']['46541'] = 1
trans['21234']['72443'] = 1
trans['21234']['83432'] = 1
trans['56443']['72443'] = 1
trans['56443']['83432'] = 1
for u1, v1 in matrix_col.items():
for u2, v2 in matrix_col.items():
for w1 in trans.keys():
for w2, c in trans[u1].items():
if u1 == str(w1) and u2 == str(w2):
print u1, u2, c
如上所述,我试图根据 matrix_col (OrderedDict)中元素的排序顺序打印 trans (defaultdict)的元素,但无法做到那。以下是我无法生成的预期输出:
11234 11234 0
11234 21234 1
11234 31223 2
11234 46541 2
11234 56443 0
11234 63324 0
11234 72443 0
11234 83432 1
11234 94334 0
21234 11234 0
21234 21234 0
21234 31223 2
21234 46541 1
21234 56443 0
21234 63324 0
21234 72443 1
21234 83432 1
21234 94334 0
31223 11234 0
31223 21234 0
31223 31223 0
31223 46541 0
31223 56443 0
31223 63324 0
31223 72443 0
31223 83432 0
31223 94334 0
...
感谢任何帮助。
答案 0 :(得分:0)
没有标准方法(我知道)根据OrderedDict上的任意排序对字典进行排序,但您总是可以按相同的方式排序。在这种情况下,只需一个默认排序即可。
for k, sub_dct in sorted(trans.items()):
for sub_k, v in sorted(sub_dct.items()):
print k, sub_k, v
我认为,另一种选择是遍历OrderedDict两次并对defaultdict进行查找。
for k in matrix_col:
for sub_k in matrix_col:
v = trans.get(k, {}).get(sub_k, 0)
print k, sub_k, trans[k][sub_k]
答案 1 :(得分:0)
我能够解决它。这是:
for u1, v1 in matrix_col.items():
for u2, v2 in matrix_col.items():
bastim = True
for w1 in trans.keys():
for w2, c in trans[u1].items():
if u1 == str(w1) and u2 == str(w2):
print u1, u2, c
bastim = False
if bastim:
print u1, u2, 0
谢谢大家。
答案 2 :(得分:0)
此迭代有效:
for u1 in matrix_col:
d = trans[u1]
# d may be empty dict
for u2 in matrix_col:
print u1, u2, d.get(u2, 0)
在此次迭代之前查看trans
:
defaultdict(<type 'dict'>, {
'21234': {'31223': 2, '46541': 1, '72443': 1, '83432': 1},
'11234': {'21234': 1, '31223': 2, '46541': 2, '83432': 1},
'56443': {'83432': 1, '72443': 1}
})
有&#39; 21234&#39;,&#39; 11234&#39;的条目。和&#39; 56443&#39;;当迭代使用另一个u1
时,d
将是一个空字典{}
。如果d.get
不存在,0
负责返回有意义的值(u2
)。
defaultdict
将为您引用的每个键添加条目,但您必须先引用它。在trans.keys()
上迭代不会生成新密钥。您的初始迭代完成了您所描述的内容 - print the elements of trans (defaultdict)
。
您的布尔值bastim
会处理同样的问题 - 填写trans
中没有的0。
如果trans
是defaultdict
defautdicts
,那么迭代可能会更简单:
def foo():
# the inner dict defaults to 0
return defaultdict(int)
trans = defaultdict(foo)
for u1 in matrix_col:
d = trans[u1]
for v1 in matrix_col:
print u1,v1, d[v1]
如果内部字典在列表中收集值
,这将更有趣def foo():
return defaultdict(list)
trans = defaultdict(foo)
并使用append
(并重复)
trans['11234']['46541'].append(2)
trans['11234']['21234'].append(1)
trans['11234']['31223'].append(2)
trans['11234']['83432'].append(1)
trans['11234']['46541'].append(5)
trans['11234']['21234'].append(3)
trans['11234']['31223'].append(4)
制造
11234 11234 []
11234 21234 [1, 3]
11234 31223 [2, 4]
11234 46541 [2, 5]
....
答案 3 :(得分:0)
我扩展了你自己的答案。这段代码似乎是等效的,运行速度提高了大约3倍,虽然不确定你是否受到CPU的限制,并且可能无法在python&lt; 2.7(operator.methodcaller)。 (显然,更好的性能选项只是使用C或尝试利用numpy矩阵运算)
items=matrix_col.items()
import operator
for (u1, v1), trans_u1_items in zip(items,map(operator.methodcaller('items'), map(trans.__getitem__,matrix_col))):
for u2, v2 in items:
bastim = True
for w1 in trans:
for w2, c in trans_u1_items:
if u1 == w1 and u2 == w2:
print u1, u2, c
bastim = False
if bastim:
pass
print u1, u2, 0