Name the iteration parts in itertools.products

I read about itertools , which seems like a very powerful module. I am particularly interested in itertools.product() , which seems to give me all combinations of iterable inputs.

However, I would like to know which of the input iterations comes out of each output. For example, a simple standard example:

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

If the user provided the inputs [1,2,3], [1, 2], I will not know in which order they entered, so getting the result

 (1, 2) 

doesn't really help, since I don’t know in what order they will be. Is there a way to provide input, for example:

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

and then getting outputs such as:

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

or

 output.foo = 1 output.bar = 2 
+4
source share
2 answers

The output of itertools.product([1, 2, 3], [1, 2]) is a series of ordered pairs, whether the first element is from [1,2,3] and the second is from [1,2] . This is guaranteed behavior.

If field names are desired, you can pass the result to named tuple . At your request, a named tuple allows you to access fields using output.foo and output.bar . Including KennyTM's idea of ​​using **items , it can be packaged into a single efficient and effective memory:

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

Here is an example call:

 >>> 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) 
+14
source

The result will always be ordered in accordance with the order of the product arguments, that is, in (1, 2) , 1 should come from [1,2,3] and 2 should come from [1,2] .

Therefore, your requirement can be satisfied by reusing itertools.product:

 def named_product(**items): names = items.keys() vals = items.values() for res in itertools.product(*vals): yield dict(zip(names, res)) 
+5
source

Source: https://habr.com/ru/post/1394200/


All Articles