3

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

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

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

4

2 回答 2

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 实例,则可以将zline 更改为

z = (tuple([[dct, operator.setitem(dct, 'picked', vval)][0] \
      for dct,vval in zip(map(dict,dcts), val)]) for val in y)
于 2012-11-14T16:34:33.723 回答
0

简单的方法是生成新的字典:

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) 
于 2012-11-14T16:44:49.983 回答