Python 在itertools.products中命名iterables的部分

Python 在itertools.products中命名iterables的部分,python,itertools,Python,Itertools,我一直在读关于itertools,它似乎是一个非常强大的模块。我特别感兴趣的是itertools.product(),它似乎提供了iterable输入的所有组合 但是,我想知道每个输出都来自哪个输入可编程项。例如,一个简单的标准示例是: itertools.product([1, 2, 3], [1, 2]) 如果用户提供了[1,2,3],[1,2]的输入,我不知道它们的顺序,因此得到 (1, 2) 这帮不了什么忙,因为我不知道他们会走哪条路。是否有提供输入的方法,如: itertools.

我一直在读关于
itertools
,它似乎是一个非常强大的模块。我特别感兴趣的是
itertools.product()
,它似乎提供了iterable输入的所有组合

但是,我想知道每个输出都来自哪个输入可编程项。例如,一个简单的标准示例是:

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


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

如果需要字段名,可以将结果强制转换为。根据您的请求,命名元组允许您使用
output.foo
output.bar
访问字段。结合KennyTM使用
**项的想法,它可以打包在一个功能中,既快速又节省内存:

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)

结果将始终按照乘积的参数顺序排序,即在
(1,2)
中,
1
必须来自
[1,2,3]
2
必须来自
[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))

从文档中我可以说,它总是按照参数的顺序来的。Felix,这是完全正确的。返回namedtuple比返回dictionary更好。后者的创建成本更高,占用更多内存,并且失去笛卡尔乘积的顺序。也就是说,+1用于创造性地使用
**项。
def named_product(**items):
    names = items.keys()
    vals = items.values()
    for res in itertools.product(*vals):
        yield dict(zip(names, res))