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

rob*_*ntw 6 python python-itertools

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

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

itertools.product([1, 2, 3], [1, 2])
Run Code Online (Sandbox Code Playgroud)

如果用户提供[1,2,3],[1,2]的输入,我将不知道他们进入了哪个顺序,因此得到的结果是

(1, 2)
Run Code Online (Sandbox Code Playgroud)

没有多大帮助,因为我不知道他们会走哪条路.是否有某种方式提供输入,如:

itertools.product(foo = [1, 2, 3], bar = [1, 2])
Run Code Online (Sandbox Code Playgroud)

然后得到如下输出:

output['foo'] = 1
output['bar'] = 2
Run Code Online (Sandbox Code Playgroud)

要么

output.foo = 1
output.bar = 2
Run Code Online (Sandbox Code Playgroud)

Ray*_*ger 17

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

如果需要字段名称,则可以将结果强制转换为命名元组.根据您的要求,命名元组允许您使用output.foo和访问字段output.bar.结合KennyTM的使用思路**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()))
Run Code Online (Sandbox Code Playgroud)

这是一个示例调用:

>>> 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)
Run Code Online (Sandbox Code Playgroud)


ken*_*ytm 5

结果总是会根据产品的参数顺序,即下令(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))
Run Code Online (Sandbox Code Playgroud)