-4

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 ()
            return
        if any(len(pool) == 0 for pool in pools):
            return
        indices = [0] * n
        yield tuple(pool[i] for pool, i in zip(pools, indices))
        while 1:
            for i in reversed(range(n)):  # right to left
                if indices[i] == len(pools[i]) - 1:
                    continue
                indices[i] += 1
                for j in range(i+1, n):
                    indices[j] = 0
                yield tuple(pool[i] for pool, i in zip(pools, indices))
                break
            else:
                return
  • 2
    It looks like you want us to write some code for you. While many users are willing to produce code for a coder in distress, they usually only help when the poster has already tried to solve the problem on their own. A good way to demonstrate this effort is to include the code you've written so far, example input (if there is any), the expected output, and the output you actually get (output, tracebacks, etc.). The more detail you provide, the more answers you are likely to receive. Check the [FAQ](http://stackoverflow.com/tour) and [How to Ask](http://stackoverflow.com/questions/how-to-ask). – TigerhawkT3 Jul 25 '16 at 15:15
  • Without `itertools` ? Then it's loops time I guess. is there a reason you wont use `itertools` ? or it's more like a challenge for urself ? – pwnsauce Jul 25 '16 at 15:16
  • 2
    1. Write the code using itertools. 2. Go to the itertools documentation. For each function you used, find the "this function is equivalent to the following code:" block. 3. Copy those blocks into your code. – Kevin Jul 25 '16 at 15:17
  • 1
    If it is always `A` and `B` -- you could use `bin()` to get the binary expansion of all numbers in the range 0 to 2**n-1 and then replace `0` by `A` and `1` by `B` in the resulting strings. – John Coleman Jul 25 '16 at 15:17
  • @JohnColeman that would be easy and smooth. Nice one – pwnsauce Jul 25 '16 at 15:18
  • 1
    I would highly recommend using the well established and tested `itertools` standard module. Reinventing the wheel is never advisable as a programmer. That being said, we have no attempt at any code here, just a request for an answer (*sounds somewhat like homework*). I would start by taking a look at the `product()` function in itertools. – ospahiu Jul 25 '16 at 15:27
  • Your edit has radically changed the meaning of your question. Before the edit it was a reasonably focused albeit ad-hoc question. Now it is overly-broad. There is an awful lot going on in itertool's `product` function, too much to be explained in a Stack Overflow answer. If you have a focused *non-duplicate* question about `yield` vs. `return` then you should ask a new question. – John Coleman Jul 25 '16 at 16:51

3 Answers3

2

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)
ospahiu
  • 3,465
  • 2
  • 13
  • 24
0

This code should do the work:

bytes = [i for i in range(2**(n))]
AB= []
for obj in bytes:
    t = str(bin(obj))[2:]
    t= '0'*(n-len(t)) + t
    AB.append(t.replace('0','A').replace('1','B'))

n being the string size wanted

Isdj
  • 1,835
  • 1
  • 18
  • 36
0

First create a list with all the possible arrangements, that's easily achievable by summing binaries:

def generate_arrangements(n):
    return [bin(i)[2:].zfill(n) for i in range(2**n)]  # 2**n is number of possible options (A,B) n times

The [2:] slices the string and remove '0b' from it and zfill(n) completes the string with 0s until the string has length of n.

Now replace all 0,1 by A,B respectively:

arrangements = [arrangement.replace('0', 'A').replace('1', 'B') for arrangement in generate_arrangements(3)]
print(arrangements)
>> ['AAA', 'AAB', 'ABA', 'ABB', 'BAA', 'BAB', 'BBA', 'BBB']

If you want to put all together you have:

def generateAB(n):
    arrangements = [bin(i)[2:].zfill(n) for i in range(2**n)]
    return [arrangement.replace('0', 'A').replace('1', 'B') for arrangement in arrangements]
Carlos Afonso
  • 1,927
  • 1
  • 12
  • 22