这只是一个例子,但给出了以下模型:
class Foo(models.model):
bar = models.IntegerField()
def __str__(self):
return str(self.bar)
def __unicode__(self):
return str(self.bar)
以下QuerySet
对象:
foobar = Foo.objects.filter(bar__lt=20).distinct()
(意思是一组带有Foo
的唯一bar <= 20
模型),如何生成foobar
的所有可能子集?理想情况下,我希望进一步限制子集,以便对x
的每个子集foobar
,f.bar
中所有x
的总和(其中f
}是Foo
类型的模型,介于某个最大值和最小值之间。
因此,例如,给定以下foobar
实例:
>> print foobar
[<Foo: 5>, <Foo: 10>, <Foo: 15>]
min=5
,max=25
,我想构建一个对象(最好是QuerySet
,但可能是一个列表),如下所示:
[[<Foo: 5>], [<Foo: 10>], [<Foo: 15>], [<Foo: 5>, <Foo: 10>],
[<Foo: 5>, <Foo: 15>], [<Foo: 10>, <Foo: 15>]]
我已经尝试过itertools
,但它似乎并不特别适合我的需求。
我认为这可以通过复杂的QuerySet
完成,但我不知道如何开始。
答案 0 :(得分:3)
S = [list(itertools.combinations(foobar,i)) for i in xrange(1, len(foobar))]
它生成非平面列表。您可以通过以下方式展平它:
list(itertools.chain.from_iterable(S))
答案 1 :(得分:1)
这将为您提供foobar
from itertools import combinations
[j for i in range(len(foobar)+1) for j in combinations(foobar,i)]
(作为列表)
from itertools import combinations
[j for i in range(len(foobar)+1) for j in combinations(foobar,i)
if minval <= sum(f.bar for f in j) <= maxval]
为minval和maxval添加过滤器给出:
>>> from itertools import combinations
>>> class Foo(object):
... def __init__(self, bar):
... self.bar=bar
... def __repr__(self):
... return "<Foo: %s>"%self.bar
...
>>> foobar=[Foo(5),Foo(10),Foo(15)]
>>> minval=5
>>> maxval=25
>>> [j for i in range(len(foobar)+1) for j in combinations(foobar,i)
if minval <= sum(f.bar for f in j) <= maxval]
[(<Foo: 5>,), (<Foo: 10>,), (<Foo: 15>,), (<Foo: 5>, <Foo: 10>), (<Foo: 5>, <Foo: 15>), (<Foo: 10>, <Foo: 15>)]
让我们创建一个类并试一试
>>> [list(j) for i in range(len(foobar)+1) for j in combinations(foobar,i) if minval <= sum(f.bar for f in j) <= maxval ]
[[<Foo: 5>], [<Foo: 10>], [<Foo: 15>], [<Foo: 5>, <Foo: 10>], [<Foo: 5>, <Foo: 15>], [<Foo: 10>, <Foo: 15>]]
如果你需要列表而不是元组,那么在
中添加它也是微不足道的{{1}}