序列中所有可能的值对组合(2项元组)-PYTHON 2.7

序列中所有可能的值对组合(2项元组)-PYTHON 2.7,python,python-2.7,tuples,counter,list-comprehension,Python,Python 2.7,Tuples,Counter,List Comprehension,我正处于数学大脑放屁的时刻,谷歌未能回答我的困惑 给定一个2项元组的序列或列表(来自计数器对象),如何快速而优雅地让python吐出这些元组的所有可能组合的线性序列或数组?我的目标是试图从计数器对象中找到结果的组合 例如,如果我有以下序列: [(500, 2), (250, 1)] 手动执行此示例,应产生以下结果: 250, 500, 750, 1000, 1250. 基本上,我认为b的范围是a*b,然后把结果列表加在一起。。。 我已经尝试过这个(其中c=计数器对象): 它会还给我:

我正处于数学大脑放屁的时刻,谷歌未能回答我的困惑

给定一个2项元组的序列或列表(来自计数器对象),如何快速而优雅地让python吐出这些元组的所有可能组合的线性序列或数组?我的目标是试图从计数器对象中找到结果的组合

例如,如果我有以下序列:

[(500, 2), (250, 1)]  
手动执行此示例,应产生以下结果:

250, 500, 750, 1000, 1250. 
基本上,我认为b的范围是a*b,然后把结果列表加在一起。。。 我已经尝试过这个(其中c=计数器对象):

它会还给我:

res = [[250], [500, 1000]]
到目前为止,很好,它通过每个元组,然后乘以x*y得到每个y。。。但是结果列表还没有包含所有的组合,第一个列表[250]需要添加到第二个列表的每个元素中。我相信任何数量的结果都是如此

现在我想我需要把这个结果列表中的每个列表依次添加到其他列表中的其他元素中。我做错了吗?我发誓应该有更简单的方法。我觉得应该有办法在一行列表中实现这一点


解决方案是递归的吗?有没有我不知道的神奇导入或内置方法?我的头很痛……

我不完全确定我是否明白你的意思,但也许你在找类似的东西

from itertools import product

def lincombs(s):
    terms, ffs = zip(*s)
    factors = product(*(range(f+1) for f in ffs))
    outs = (sum(v*f for v,f in zip(terms, ff)) for ff in factors if any(ff))
    return outs

>>> list(lincombs([(500, 2), (250, 1)]))
[250, 500, 750, 1000, 1250]
>>> list(lincombs([(100, 3), (10, 3)]))
[10, 20, 30, 100, 110, 120, 130, 200, 210, 220, 230, 300, 310, 320, 330]

v*f
可以避免以下情况的乘法:

>>> from itertools import product
>>> terms = [(500, 2), (250, 1)]
>>> map(sum, product(*[xrange(0, v*a+1, v) for v, a in terms]))
[0, 250, 500, 750, 1000, 1250]
要获得无重复项的排序输出,请执行以下操作:

from itertools import groupby, imap
from operator import itemgetter

it = imap(itemgetter(0), groupby(sorted(it)))

虽然您使用的
排序(set(it))
在这种情况下是可以的。

如果
750
在解决方案集中,为什么不
1500
?你能澄清一下结果集应该是
[250*1,(500*1或250*2),(500*1+250*1),(500*2或250*2+500*1),(500*2+250*1)]
我不知道你是如何从输入序列中得到这些结果的。你能解释得更清楚一点吗?它是一个计数器对象,所以对于计数器中的每个元组,我用英语读它为:x=“this item”,y=“exists this multiples”,所以我想找到这些项的计数的所有组合。1500不应在解决方案集中,因为无法使用“看到的项目数量”来合计该数量。你能得到的最高值是1250->500+500+250。或者,在长格式中,同时使用500个元组计数和250个元组计数。希望这能澄清问题。为了充分解释,我将亲自出马寻找所有解决方案:
(250*1)=250(500*1)=500(500*1)+(250*1)=750(500*1)+(500*1)=1000(500*1+(500*1)+(250*1)=1250
不应该有其他解决方案。@ACVentures这样您就可以使用元组(A,B)中的项A了一次最多B次?哇,好的,这看起来确实有效。谢谢你!但是,我完全不知道它是如何工作的。你能告诉我一些地方,我可以了解这段代码是如何工作的吗?特别是乘积方法中的*和zip方法。另外,如果你从500,3和250,2开始,而不是从我的in开始,这将产生重复的结果初始示例,但很容易过滤掉。非常擅长4行+导入!您认为使用单个列表理解行可以做到这一点吗?@ACVentures:stararg语法可用于任何函数:
f(*[a,b,c])
f(a,b,c)相同
。您可以将
产品看作笛卡尔产品,例如
列表(产品(范围(2+1),范围(1+1))==[(0,0),(0,1),(1,0),(1,1),(2,0),(2,1)]
对于问题中的示例。顺便说一句,我不明白您为什么从问题中排除所有系数均为零的组合。如果您想在删除
时包含它(如果有)(ff)
。我对zip做了一些研究,以及神奇星号对元组的打包和解包做了些什么。然后我对同样使用神奇星号的乘积方法做了一些研究。直到关于神奇星号和生成器表达式……python的美妙之处在于,它似乎已经有了一些“刚好可以”的东西你需要的。对于我的特定用途,不应该有结果为零,或者乘以零,因此它们将被忽略。最后,我能够通过点击一个排序(set(outs))来简化“outs”返回,这将产生一个很好的升序列表
from itertools import groupby, imap
from operator import itemgetter

it = imap(itemgetter(0), groupby(sorted(it)))