1
A=[1,2,3,4,5,6,7]
B=[a,b,c,d,e,f,g,h,i,j,k,l]
C=[]

I want to replace the values in 'A' by the values of 'B' at maximum 3 places without changing its existing order, and store all the possible changes in C.

Out put is supposed to be like below

C=[(1,i,3,4,5,a,7),
   (1,a,b,4,a,6,7),
   (1,2,3,a,5,6,7),
   (1,b,a,4,5,6,),
   (c,2,3,4,5,6,7),
   ......]

Couldn't come up any code/logic/flow for it. Thanks

I tried for loops but didnt help much.

A=[1,2,3,4,5,6,7] 
B=['a','b','c','d','e','f','g','h','i','j','k','l'] 
C=[] 
for i in A: 
   for j in B: 
      A.remove(j) A.append(i) 
      print(A)
shivam
  • 596
  • 2
  • 9

2 Answers2

1

Let's think about this

We need a random number of replacements, namely 1-3. We can use random.randint to generate this number, then random.sample to get some random elements from A and B to switch.

Code

import random

# Define variables
A = [1,2,3,4,5,6,7]
B = ["a","b","c","d","e","f","g","h","i","j","k","l"]
C = []

# Iterate how ever many times, i.e. 10
for i in range(10):
    results = A
    swaps = random.randint(1, 3)
    swapA = random.sample(A, swaps)
    swapB = random.sample(B, swaps)
    
    # Group the swaps together, so we don't need to use an extra loop
    zipped = list(zip(swapA, swapB))

    # Replace numbers with letters
    for i in range(len(results)):
        # Check if this is the right place to swap
        for swap in zipped:
            if results[i] == swap[0]:
                # Swap the two numbers!
                results[i] = swap[1]

    # Add to results list
    C.append(results)

# View results!
print(C)
Larry the Llama
  • 958
  • 3
  • 13
  • When I run this, I get 10 identical lists. – Mark Nov 30 '21 at 03:22
  • it is changing just one value that's too at first place only. – shivam Nov 30 '21 at 03:30
  • I'm getting: `[['g', 2, 3, 4, 5, 6, 7], ['g', 2, 3, 4, 5, 6, 7], ['g', 2, 3, 4, 5, 6, 7], ['g', 2, 3, 4, 5, 6, 7], ['g', 2, 3, 4, 5, 6, 7], ['g', 2, 3, 4, 5, 6, 7], ['g', 2, 3, 4, 5, 6, 7], ['g', 2, 3, 4, 5, 6, 7], ['g', 2, 3, 4, 5, 6, 7], ['g', 2, 3, 4, 5, 6, 7]]`. Am I doing it wrong? – Mark Nov 30 '21 at 03:39
  • @Mark I just added a `list(zip(...))` list around zip and it is all working now - I wrote the code without running it early, hopefully it should work for you now. I also hope that the answer makes intuitive sense. – Larry the Llama Nov 30 '21 at 10:03
  • is there any way to define the range up to the maximum unique possible permutants (Pmax) ? `for i in range(Pmax)` – shivam Dec 01 '21 at 01:20
  • @CD100 yes it is possible, but not only is that number extremely high, but also you would have to ditch the random and use a number-decoding system to calculate any number between 0 and Pmax and use that to determine how you would permute the data - I came up with a method of this (I'm sure it has been done before) but it is a little long, requiring modulus, etc. – Larry the Llama Dec 01 '21 at 02:36
1

You can create a combination by randomly selecting a number of replacements (1,2 or 3), then select that number of distinct values and random letters. Use zip to create a mapping of values to replace with the selected letters and use the mapping to form the combination tuple. Add it to C and loop until you have the desired number of combinations in C:

A=[1,2,3,4,5,6,7]
B=['a','b','c','d','e','f','g','h','i','j','k','l']
C=[]

import random
while len(C)<10: # use the number of combinations you need
    count   = random.randint(1,3)              # how many replacements
    values  = random.sample(A,count)           # select values to replace
    letters = random.choices(B,k=count)        # select letters
    repl    = dict(zip(values,letters))        # replacement mapping
    combo   = tuple(repl.get(i,i) for i in A)  # combination tuple
    C.append(combo)                            # add combination

print(*C,sep="\n")
('a', 2, 3, 'j', 5, 'c', 7)
('g', 2, 3, 4, 5, 'd', 'f')
(1, 'f', 'g', 4, 5, 6, 'e')
(1, 2, 3, 'c', 'g', 6, 7)
(1, 2, 'j', 4, 5, 6, 7)
(1, 2, 3, 4, 5, 6, 'l')
(1, 2, 'i', 'e', 'f', 6, 7)
(1, 2, 3, 4, 5, 'l', 7)
('c', 2, 3, 4, 5, 6, 7)
('h', 2, 3, 4, 5, 6, 7) 

If you need the combinations to be distinct, use a set for C instead of a list

If you want all possible combinations in C, you can generate them using product() and combinations() from itertools:

A=[1,2,3,4,5,6,7]
B=['a','b','c','d','e','f','g','h','i','j','k','l']
C=[]

from itertools import product,combinations

for count in (1,2,3):
    for positions in combinations(range(len(A)),count):
        for letters in product(B,repeat=count):
            combo = A.copy()
            for p,c in zip(positions,letters):
                combo[p] = c
            C.append(tuple(combo))

output:

print(len(C)) # 63588
print(C)
[('a', 2, 3, 4, 5, 6, 7), 
 ('b', 2, 3, 4, 5, 6, 7), 
 ('c', 2, 3, 4, 5, 6, 7), 
 ...
 (1, 2, 3, 4, 'l', 'l', 'j'), 
 (1, 2, 3, 4, 'l', 'l', 'k'), 
 (1, 2, 3, 4, 'l', 'l', 'l')]]
Alain T.
  • 40,517
  • 4
  • 31
  • 51
  • @Alian Is there any way to find the maximum number of possible permutants (Pmax) ie `while len(C) < Pmax:` – shivam Dec 01 '21 at 01:02
  • It is but you should generate them systematically rather than randomly (randomly would take a long time). If you only need to know how many there are you can compute it mathematically: `C(7,1)*12^1 + C(7,2)*12^2 + C(7,3)*12^3 = 63588` where C(n,r) is the combination count of r in n: n!/r!(n-r)! – Alain T. Dec 01 '21 at 03:59