基于dicts内部值的所有可能的dicts组合

时间:2012-11-14 16:04:20

标签: python combinations itertools

我想根据其中的值生成使用dicts的所有可能方法。为了在代码中解释,我有:

a = {'name' : 'a', 'items': 3}
b = {'name' : 'b', 'items': 4}
c = {'name' : 'c', 'items': 5}

我希望能够从这些词汇中挑选出(确切地说)7个项目,以及我能够做到的所有可能方式。

所以:

x = itertools.product(range(a['items']), range(b['items']), range(c['items']))
y = itertools.ifilter(lambda i: sum(i)==7, x)

会给我:

(0, 3, 4)
(1, 2, 4)
(1, 3, 3)
...

我真正喜欢的是:

({'name' : 'a', 'picked': 0}, {'name': 'b', 'picked': 3}, {'name': 'c', 'picked': 4})
({'name' : 'a', 'picked': 1}, {'name': 'b', 'picked': 2}, {'name': 'c', 'picked': 4})
({'name' : 'a', 'picked': 1}, {'name': 'b', 'picked': 3}, {'name': 'c', 'picked': 3})
....

关于如何做到这一点的任何想法,干净利落?

2 个答案:

答案 0 :(得分:0)

这是

import itertools
import operator

a = {'name' : 'a', 'items': 3}
b = {'name' : 'b', 'items': 4}
c = {'name' : 'c', 'items': 5}

dcts = [a,b,c]

x = itertools.product(range(a['items']), range(b['items']), range(c['items']))
y = itertools.ifilter(lambda i: sum(i)==7, x)
z = (tuple([[dct, operator.setitem(dct, 'picked', vval)][0] \
       for dct,vval in zip(dcts, val)]) for val in y)
for zz in z:
    print zz

您可以修改它以创建词典副本。如果您在每次迭代时都需要新的dict实例,则可以将z行更改为

z = (tuple([[dct, operator.setitem(dct, 'picked', vval)][0] \
      for dct,vval in zip(map(dict,dcts), val)]) for val in y)

答案 1 :(得分:0)

简单的方法是生成新的dicts:

names = [x['name'] for x in  [a,b,c]]
ziped = map(lambda x: zip(names, x), y)
maped = map(lambda el: [{'name': name, 'picked': count} for name, count in el],
            ziped)