All combinations from multiple lists with different indices

Question:

I have N lists of M elements (each list), N < M.

I would like to have all the combinations from them with the conditions:

  • each combination has N elements,
  • all indices in combination (from the original list) are unique.

Example for 3(N) lists of 4(M) each:

list1 = [d11,d12,d13,d14]
list2 = [d21,d22,d23,d24]
list3 = [d31,d32,d33,d34]

All expected combinations:

comb1 = [d11,d22,d33]
comb2 = [d11,d22,d34]
comb3 = [d11,d23,d32]
comb4 = [d11,d23,d34]
comb5 = [d11,d24,d32]
comb6 = [d11,d24,d33]
comb7 = [d12,d21,d33]
comb8 = [d12,d21,d34]
comb9 = [d12,d23,d31]
comb10 = [d12,d23,d34]
comb11 = [d12,d24,d31]
comb12 = [d12,d24,d33]
comb13 = [d13,d21,d32]
comb14 = [d13,d21,d34]
comb15 = [d13,d22,d31]
comb16 = [d13,d22,d34]
comb17 = [d13,d24,d31]
comb18 = [d13,d24,d32]
comb19 = [d14,d21,d32]
comb20 = [d14,d21,d33]
comb21 = [d14,d22,d31]
comb22 = [d14,d22,d33]
comb23 = [d14,d23,d31]
comb24 = [d14,d23,d32]

Not expected combinations:

notcomb1 = [d11,d21,d32] (d11 and d21 have the same index 0 from the original list1 and list2)

notcomb1 = [d11,d22,d31] (d11 and d31 have the same index 0 from the original list1 and list3)

How to get this by python?

Asked By: HungLam

||

Answers:

i think you are asking the permutations of picking N from M.

from itertools import permutations

for idx_1, idx_2, idx_3 in permutations(range(4), 3):
    print(idx_1, idx_2, idx_3)
Answered By: qaqualia

To get the columns to sample from, use itertools.combinations

To get the rows to sample from, use itertools.permutations

import itertools

data = [
    ["d11", "d12", "d13", "d14"],
    ["d21", "d22", "d23", "d24"],
    ["d31", "d32", "d33", "d34"],
]

for columns in itertools.combinations(range(len(data[0])), r=len(data)):
    for rows in itertools.permutations(range(len(data))):
        print([data[y][x] for x,y in zip(columns, rows)])
['d11', 'd22', 'd33']
['d11', 'd32', 'd23']
['d21', 'd12', 'd33']
['d21', 'd32', 'd13']
['d31', 'd12', 'd23']
['d31', 'd22', 'd13']
['d11', 'd22', 'd34']
['d11', 'd32', 'd24']
['d21', 'd12', 'd34']
['d21', 'd32', 'd14']
['d31', 'd12', 'd24']
['d31', 'd22', 'd14']
['d11', 'd23', 'd34']
['d11', 'd33', 'd24']
['d21', 'd13', 'd34']
['d21', 'd33', 'd14']
['d31', 'd13', 'd24']
['d31', 'd23', 'd14']
['d12', 'd23', 'd34']
['d12', 'd33', 'd24']
['d22', 'd13', 'd34']
['d22', 'd33', 'd14']
['d32', 'd13', 'd24']
['d32', 'd23', 'd14']
Answered By: flakes
from itertools import permutations

data = [
    ["d11", "d12", "d13", "d14"],
    ["d21", "d22", "d23", "d24"],
    ["d31", "d32", "d33", "d34"],
]

for p in permutations(zip(*data), len(data)):
    print([v[i] for i, v in enumerate(p)])

Output (Attempt This Online!):

['d11', 'd22', 'd33']
['d11', 'd22', 'd34']
['d11', 'd23', 'd32']
['d11', 'd23', 'd34']
['d11', 'd24', 'd32']
['d11', 'd24', 'd33']
['d12', 'd21', 'd33']
['d12', 'd21', 'd34']
['d12', 'd23', 'd31']
['d12', 'd23', 'd34']
['d12', 'd24', 'd31']
['d12', 'd24', 'd33']
['d13', 'd21', 'd32']
['d13', 'd21', 'd34']
['d13', 'd22', 'd31']
['d13', 'd22', 'd34']
['d13', 'd24', 'd31']
['d13', 'd24', 'd32']
['d14', 'd21', 'd32']
['d14', 'd21', 'd33']
['d14', 'd22', 'd31']
['d14', 'd22', 'd33']
['d14', 'd23', 'd31']
['d14', 'd23', 'd32']
Answered By: Kelly Bundy

This is basically m-length permutations of n indices:

from itertools import permutations

data = [
    ["d11", "d12", "d13", "d14"],
    ["d21", "d22", "d23", "d24"],
    ["d31", "d32", "d33", "d34"],
]
for indices in permutations(range(len(data[0])), len(data)):
    print([lst[index] for lst, index in zip(data, indices)])

This outputs:

['d11', 'd22', 'd33']
['d11', 'd22', 'd34']
['d11', 'd23', 'd32']
['d11', 'd23', 'd34']
['d11', 'd24', 'd32']
['d11', 'd24', 'd33']
['d12', 'd21', 'd33']
['d12', 'd21', 'd34']
['d12', 'd23', 'd31']
['d12', 'd23', 'd34']
['d12', 'd24', 'd31']
['d12', 'd24', 'd33']
['d13', 'd21', 'd32']
['d13', 'd21', 'd34']
['d13', 'd22', 'd31']
['d13', 'd22', 'd34']
['d13', 'd24', 'd31']
['d13', 'd24', 'd32']
['d14', 'd21', 'd32']
['d14', 'd21', 'd33']
['d14', 'd22', 'd31']
['d14', 'd22', 'd33']
['d14', 'd23', 'd31']
['d14', 'd23', 'd32']

Demo: https://replit.com/@blhsing/BlueDimgreyTests

Answered By: blhsing