I am trying to create a list of numbers from 0-9999
using itertools.product
. I am able to create a list from 0000-9999
by doing the following:
numbers = ['0','1','2','3','4','5','6','7','8','9']
itertools.product(numbers,numbers,numbers,numbers)
And while I want entries like 0001
, I would also like to get 001
, 01
, and 1
.
What would be the most effective way to include these? Should I make calls to itertools.product(numbers,numbers,numbers)
and itertools.product(numbers,numbers)
and then somehow combine these with the original or is there a cleaner way?
If I should make two other calls and combine, can someone point me towards how this would be done? I attempted to use .append()
, but it throws this error:
'itertools.product' object has no attribute 'append'
Thanks for any help.
Performance improvement on existing answers:
omitting
list()
/[*...]
wrapping if you're just iterating the results.The performance improves significantly (not so much in this case, but dramatically for larger products) on the CPython reference interpreter as (implementation details here):
product
has an optimization that reuses the resulttuple
(including not needing to set the majority of the values in it) if no references exist when the next result is requested. This optimization isn't available to listcomps and genexprs (the loop structure keeps a reference to the resultingtuple
alive just long enough that a reference exists when it's determining if it can reuse thetuple
for the next result), butmap(''.join
avoids that (it only holds the reference to thetuple
long enough to call the mapper function, discarding it before it yields the result of the mapper).Even in this case, the speedup is significant, percentage-wise, demonstrated with
ipython
microbenchmarks (in this case, on a Linux x64 3.6 install):As noted, the gains are large only in percentage terms here (~27% runtime reduction); 6.7 μs is pretty trivial in the grand scheme of things. But if the
range
to cover gets larger and/or the set ofnumbers
toproduct
over gets bigger, it matters more; fornumbers = '0123456789'
andrange(1, 8)
, the reduction is from 2.54 s to 1.67 s; asymptotically the savings appears to be a savings of roughly a third, and when the total cost is measured in seconds, reducing that cost by a third is meaningful.You could use a nested listcomp or genexp (reduced in size here for display purposes):