在 Python 中测试所有组合

发布于 2024-10-16 00:34:58 字数 256 浏览 3 评论 0原文

我有两组选项:

optionList1 = [a1,a2,a3,...,an]
optionList2 = [b1,b2,b3,...,bn]

选项列表中的元素数量不一定相等,我必须从第一个选项列表中选择两次。如何确保我已尝试了第一个列表中的 2 个选项和第二个列表中的一个选项的每种组合。下面是一个选择集示例...

selectedOptions = [an1,an2,bn]

I have two sets of options:

optionList1 = [a1,a2,a3,...,an]
optionList2 = [b1,b2,b3,...,bn]

The number of elements in the optionlists are not necessarily equal and I have to choose from the first optionlist twice. How do I ensure that I have tried every combination of 2 options from the first list and one from the second list. An example selection set below...

selectedOptions = [an1,an2,bn]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

赢得她心 2024-10-23 00:34:58

假设您不希望第一个列表中出现重复项,则合并来自 itertoolsproductpermutations

>>> from itertools import product,permutations
>>> o1 = 'a1 a2 a3'.split()
>>> o2 = 'b1 b2 b3'.split()
>>> for (a,b),c in product(permutations(o1,2),o2):
...     print a,b,c
... 
a1 a2 b1
a1 a2 b2
a1 a2 b3
a1 a3 b1
a1 a3 b2
a1 a3 b3
a2 a1 b1
a2 a1 b2
a2 a1 b3
a2 a3 b1
a2 a3 b2
a2 a3 b3
a3 a1 b1
a3 a1 b2
a3 a1 b3
a3 a2 b1
a3 a2 b2
a3 a2 b3

Combine product and permutations from itertools assuming you don't want duplicates from the first list:

>>> from itertools import product,permutations
>>> o1 = 'a1 a2 a3'.split()
>>> o2 = 'b1 b2 b3'.split()
>>> for (a,b),c in product(permutations(o1,2),o2):
...     print a,b,c
... 
a1 a2 b1
a1 a2 b2
a1 a2 b3
a1 a3 b1
a1 a3 b2
a1 a3 b3
a2 a1 b1
a2 a1 b2
a2 a1 b3
a2 a3 b1
a2 a3 b2
a2 a3 b3
a3 a1 b1
a3 a1 b2
a3 a1 b3
a3 a2 b1
a3 a2 b2
a3 a2 b3
梦回梦里 2024-10-23 00:34:58

假设您不希望 list1 中出现重复的条目,则可以使用以下生成器来迭代所有组合:

def combinations(list1, list2):
    return ([opt1, opt2, opt3]
            for i,opt1 in enumerate(list1)
            for opt2 in list1[i+1:]
            for opt3 in list2)

但是,这不会以不同的顺序从 list1 中选择相同的选项。如果你想同时获得 [a1, a2, b1] 和 [a2, a1, b1] 那么你可以使用:

def combinations(list1, list2):
    return ([opt1, opt2, opt3]
            for opt1 in list1
            for opt2 in list1
            for opt3 in list2 if opt1 != opt2)

Assuming you don't want duplicate entries from list1, here's a generator that you can use to iterate over all combinations:

def combinations(list1, list2):
    return ([opt1, opt2, opt3]
            for i,opt1 in enumerate(list1)
            for opt2 in list1[i+1:]
            for opt3 in list2)

This, however, doesn't select the same options from list1 in different orderings. If you want to get both [a1, a2, b1] and [a2, a1, b1] then you can use:

def combinations(list1, list2):
    return ([opt1, opt2, opt3]
            for opt1 in list1
            for opt2 in list1
            for opt3 in list2 if opt1 != opt2)
丿*梦醉红颜 2024-10-23 00:34:58

您可以使用 itertools.product 来实现此目的。它返回所有可能的组合。

例如,

for a1, a2, b in itertools.product(optionlist1,optionlist1,optionlist2):
    do_something(a1,a2,b)

这将产生“双精度”为 [a1,a1,b2] 和 [a2,a3,b2],[a3,a2,b2]。您可以使用过滤器解决此问题。以下内容可防止任何双打*:

for a1,a2,b in itertools.ifilter(lambda x: x[0]<x[1], itertools.product(optionlist1,optionlist1,optionlist2)):
    do_something(a1,a2,b)

(*) 这假设选项具有某种自然顺序,所有原始值都是这种情况。

答案也很好。我写了一些代码来比较它们:

from itertools import ifilter, product
import random
from timeit import repeat

def generator_way(list1, list2):
    def combinations(list1, list2):
        return ([opt1, opt2, opt3]
                for i,opt1 in enumerate(list1)
                for opt2 in list1[i+1:]
                for opt3 in list2)
    count = 0
    for a1,a2,b in combinations(list1,list2):
        count += 1

    return count

def itertools_way(list1,list2):
    count = 0
    for a1,a2,b in ifilter(lambda x: x[0] < x[1], product(list1,list1,list2)):
        count += 1
    return count

list1 = range(0,100)
random.shuffle(list1)
list2 = range(0,100)
random.shuffle(list2)

print sum(repeat(lambda: generator_way(list1,list2),repeat = 10, number=1))/10
print sum(repeat(lambda: itertools_way(list1,list2),repeat = 10, number=1))/10

结果是:

0.189330005646
0.428138256073

所以生成器方法更快。然而,速度并不是一切。就我个人而言,我发现我的代码“更干净”,但选择权在你!

(顺便说一句,它们给出了相同的计数,因此两者同样正确。)

You can use itertools.product for this. It returns all possible combinations.

For example

for a1, a2, b in itertools.product(optionlist1,optionlist1,optionlist2):
    do_something(a1,a2,b)

This will produce "doubles" as [a1,a1,b2] and [a2,a3,b2],[a3,a2,b2]. You can fix this with a filter. The following prevents any doubles*:

for a1,a2,b in itertools.ifilter(lambda x: x[0]<x[1], itertools.product(optionlist1,optionlist1,optionlist2)):
    do_something(a1,a2,b)

(*) This assumes that the options have some natural ordering which will be the case with all primitive values.

shang's answer is also very good. I wrote some code to compare them:

from itertools import ifilter, product
import random
from timeit import repeat

def generator_way(list1, list2):
    def combinations(list1, list2):
        return ([opt1, opt2, opt3]
                for i,opt1 in enumerate(list1)
                for opt2 in list1[i+1:]
                for opt3 in list2)
    count = 0
    for a1,a2,b in combinations(list1,list2):
        count += 1

    return count

def itertools_way(list1,list2):
    count = 0
    for a1,a2,b in ifilter(lambda x: x[0] < x[1], product(list1,list1,list2)):
        count += 1
    return count

list1 = range(0,100)
random.shuffle(list1)
list2 = range(0,100)
random.shuffle(list2)

print sum(repeat(lambda: generator_way(list1,list2),repeat = 10, number=1))/10
print sum(repeat(lambda: itertools_way(list1,list2),repeat = 10, number=1))/10

And the result is:

0.189330005646
0.428138256073

So the generator method is faster. However, speed is not everything. Personally I find my code 'cleaner', but the choice is yours!

(Btw, they give both identical counts, so both are equally correct.)

花落人断肠 2024-10-23 00:34:58

在我看来,您正在寻找 itertools.product()

>>> options_a = [1,2]
>>> options_b = ['a','b','c']
>>> list(itertools.product(options_a, options_a, options_b))
[(1, 1, 'a'),
 (1, 1, 'b'),
 (1, 1, 'c'),
 (1, 2, 'a'),
 (1, 2, 'b'),
 (1, 2, 'c'),
 (2, 1, 'a'),
 (2, 1, 'b'),
 (2, 1, 'c'),
 (2, 2, 'a'),
 (2, 2, 'b'),
 (2, 2, 'c')]

It sounds to me like you're looking for itertools.product()

>>> options_a = [1,2]
>>> options_b = ['a','b','c']
>>> list(itertools.product(options_a, options_a, options_b))
[(1, 1, 'a'),
 (1, 1, 'b'),
 (1, 1, 'c'),
 (1, 2, 'a'),
 (1, 2, 'b'),
 (1, 2, 'c'),
 (2, 1, 'a'),
 (2, 1, 'b'),
 (2, 1, 'c'),
 (2, 2, 'a'),
 (2, 2, 'b'),
 (2, 2, 'c')]
小鸟爱天空丶 2024-10-23 00:34:58

一种方法是使用 itertools.product

for x, y, z in itertools.product(optionlist1,optionlist1,optionlist2):
    print x,y,z

One way to do is to use itertools.product.

for x, y, z in itertools.product(optionlist1,optionlist1,optionlist2):
    print x,y,z
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文