Python:根据OrderedDict中的顺序在defaultdict中打印元素

时间:2015-10-03 02:43:27

标签: python numpy ordereddictionary defaultdict

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

感谢任何帮助。

4 个答案:

答案 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。

如果transdefaultdict 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