7

我一直在阅读 about itertools,这似乎是一个非常强大的模块。我特别感兴趣的是itertools.product()哪个似乎给了我所有可迭代输入的组合。

但是,我想知道每个输出来自哪个输入迭代。例如,一个简单的标准示例是:

itertools.product([1, 2, 3], [1, 2])

如果用户提供了 [1,2,3], [1, 2] 的输入,我将不知道他们输入的顺序,所以得到的结果

(1, 2)

没有多大帮助,因为我不知道他们会朝哪个方向走。是否有某种方式提供输入,例如:

itertools.product(foo = [1, 2, 3], bar = [1, 2])

然后得到如下输出:

output['foo'] = 1
output['bar'] = 2

或者

output.foo = 1
output.bar = 2
4

2 回答 2

20

的输出itertools.product([1, 2, 3], [1, 2])是一系列有序对,无论第一个元素来自[1,2,3],第二个元素来自[1,2]。这是有保证的行为。

如果需要字段名称,您可以将结果转换为命名元组。根据您的要求,命名元组允许您使用output.foo和访问字段output.bar。结合 KennyTM 的 using 思想**items,可以将其打包成一个快速且内存高效的函数:

from itertools import product, starmap
from collections import namedtuple

def named_product(**items):
    Product = namedtuple('Product', items.keys())
    return starmap(Product, product(*items.values()))

这是一个示例调用:

>>> for output in named_product(foo=[1,2,3], bar=[1,2]):
        print output

Product(foo=1, bar=1)
Product(foo=1, bar=2)
Product(foo=2, bar=1)
Product(foo=2, bar=2)
Product(foo=3, bar=1)
Product(foo=3, bar=2)
于 2012-02-01T15:15:42.367 回答
5

结果将始终根据产品的参数顺序进行排序,即(1, 2)must 1come from[1,2,3]2must come from [1,2]

因此,您可以通过重用 itertools.product 来满足您的要求:

def named_product(**items):
    names = items.keys()
    vals = items.values()
    for res in itertools.product(*vals):
        yield dict(zip(names, res))
于 2012-02-01T15:17:58.790 回答