ddas
ddas

Reputation: 199

Insert a number of same new element in between the elements of a list in all possible ways in Python

I have a list mylist=[1,2] and I want to insert maximum len(mylist)+1 number of an element 'A' between the elements of the list in all possible ways. The output should be something like these,

[1, 2]    

['A', 1, 2]
[1, 'A', 2]
[1, 2, 'A']

['A', 1,'A', 2]
['A',1, 2, 'A']
[1, 'A', 2,'A']

['A', 1,'A', 2, 'A']

So far I am able to insert only one 'A' in the list in all possible ways. Here is my code,

m = 3    
mylist = list(range(1,m))    
for j in range (len(mylist)+1):
    newlist = mylist[:j] + ['A'] + mylist[j:]
    print(newlist)

and the output is,

['A', 1, 2]
[1, 'A', 2]
[1, 2, 'A']

I am stuck in next steps, when I have to insert two 'A' in between the elements of the list. Need help.

Upvotes: 0

Views: 59

Answers (1)

Rory Daulton
Rory Daulton

Reputation: 22564

Take your list, say [1,2], and consider the spaces between the elements. Since there are two elements in our example, there are three spaces. Let's call them 0, 1, 2. You want to place your letter 'A' in those spaces. Though you do not say so, it appears from your example that at most one letter is to go in each space, so there is no repetition.

Therefore you want to get all possible subsets of the set {0, 1, 2}. For each of those sets, place a letter 'A' at that space in that set.

The set of all subsets is called the "power set". Python does not quite have that built in, but there are several ways to get it. Here is one way that uses the itertools built-in module.

import itertools

def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    s = list(iterable)
    return itertools.chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

Use that to get your sets of spaces, then use each set to insert your 'A's into the list.

If you really want blank lines in your output between groups of lists, you may prefer to use the itertools.combinations(s, r) function directly--this gives all subsets of set s of size r. Loop over r and print the resulting lists, and print a blank line after each value of r. Given the particular output that you want, this is probably the best option.

Another way to get the powerset uses the powerset() method of the FiniteSet class of sympy. The sympy module is not a standard part of Python, though if you installed Python using the Anaconda installation you already have it.

Yet another way to get the powerset involves you making your own recursive or back-tracking routine. This is the most difficult way but this avoids using any modules.

Here is code implementing the "best option," using itertools.combinations directly. I changed your variables to have better names and content.

from itertools import combinations

mylistsize = 2
myinsertitem = 'A'
mylist = list(range(1, mylistsize+1))

allspaceplaces = list(range(mylistsize+1))
for numinserts in range (mylistsize + 2):
    if numinserts:
        print()
    for spaceplaces in combinations(allspaceplaces, numinserts):
        newlist = []
        lo = 0
        for hi in spaceplaces:
            newlist.extend(mylist[lo:hi])
            newlist.append(myinsertitem)
            lo = hi
        newlist.extend(mylist[lo:])
        print(newlist)

The printout from that code is

[1, 2]

['A', 1, 2]
[1, 'A', 2]
[1, 2, 'A']

['A', 1, 'A', 2]
['A', 1, 2, 'A']
[1, 'A', 2, 'A']

['A', 1, 'A', 2, 'A']

Upvotes: 2

Related Questions