Reputation: 160
list_a = []
for color in [True,False]:
for piece in range(1,7):
list_a = list_a + function(piece,color)
Here the function(piece,color)
returns a list, which I want to join and finally return the long list, can itertools.chain
be used here? because I think it might be faster. I am only displaying an example, but in my actual code the loop runs about 100,000 times, which is why I am looking for a faster method.
Upvotes: 4
Views: 1697
Reputation: 95957
If you really want to use itertools.chain
:
>>> from itertools import product, chain
>>> list_a = list(chain.from_iterable(function(piece, color) for piece, color in product([True, False], range(1, 7))))
Of course, if you use list_a += function(piece, color)
this would likely be just as fast (maybe faster?).
The problem with list_a = list_a + function(piece, color)
is that this line is quadratic in it's input, because it builds an entirely new list, whereas list_a += function(piece, color)
is the equivalent of using extend
, which for Python lists is amortized constant time, so the inner part stays linear instead of quadratic.
Upvotes: 3
Reputation: 44848
You can use itertools.starmap
, although you'll still have the loops, you can't really escape from them:
result_generator = starmap(function, ((piece, color) for piece in range(1,7) for color in [True,False]))
list_a = list(result_generator)
Then, use itertools.product
like this:
result_generator = starmap(function, product(range(1,7), [True,False]))
Upvotes: 0
Reputation: 70602
I'm going to answer the question you should have asked instead ;-)
This:
list_a = list_a + function(piece,color)
takes time quadratic in the number of times it's executed. Each time, a brand new list object is created, copying the entirety of the old list_a
and the new list.
So if it's executed many times, you can get a huge improvement by changing it to this:
list_a.extend(function(piece,color))
Then list_a
is extended "in place" whenever possible; under the covers, it may need to make a copy to a larger memory area from time to time, but overall the amortized time is linear in the number of times it's executed.
Upvotes: 6
Reputation: 1038
yield from
seems to be the simple solution here.
def generator():
for color in [True,False]:
for piece in range(1,7):
yield from function(piece,color)
Upvotes: 1