so basically i want to understand the concept of product() function in itertools. i mean what is the different between yield and return. And can this code be shorten down anyway.
def product1(*args, **kwds):pools = map(tuple, args) * kwds.get('repeat', 1)n = len(pools)if n == 0:yield ()returnif any(len(pool) == 0 for pool in pools):returnindices = [0] * nyield tuple(pool[i] for pool, i in zip(pools, indices))while 1:for i in reversed(range(n)): # right to leftif indices[i] == len(pools[i]) - 1:continueindices[i] += 1for j in range(i+1, n):indices[j] = 0yield tuple(pool[i] for pool, i in zip(pools, indices))breakelse:return
I would highly recommend using the well established and tested itertools
standard module. Reinventing the wheel is never advisable as a programmer. That said, I would start by taking a look at the product()
function in itertools.
As for not using itertools()
, this problem is essentially a cartesian product problem (n-permutations with duplicates allowed). This is where recursion helps us! One possible solution below:
Method Body:
result = []
def permutations(alphabet, repeat, total = ''):if repeat >= 1:for i in alphabet:# Add the subsolutions. permutations(alphabet, repeat - 1, total + i) else:result.append(total)return result
And when we call with permutations()
Sample Outputs:
permutations('ab', 3) ->
$ ['aaa', 'aab', 'aba', 'abb', 'baa', 'bab', 'bba', 'bbb']
permutations('ab', 3) ->
$ ['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc', 'baa','bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 'caa', 'cab', 'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc']
permutations('ab', 1) ->
$ ['a', 'b']
How does it work?
This method works by nesting for loops in a recursive manner repeat-times. We then accumulate the result of the sub-solutions, appending to a result list. So if we use 4 as our repeat value, out expanded iterative trace of this problem would look like the following:
for i in alphabet:for j in alphabet:for k in alphabet:for l in alphabet:result.append(i + j + k + l)