Surakri Karto
Surakri Karto

Reputation: 13

How to make this function return pair of combination from array rows in Python?

i have the following function

import numpy as np

a = [['a','b','c'],['d','e','f'],['g','h','i'],['j','k','l']]
b = np.array(a)

def func01(matrix):
    m,n = np.shape(matrix)
    for jump in range (m-1):
        for row in range (jump):
            for col in range (n):
                print (matrix[row][col],matrix[row+jump][col])

func01(b)

this results in:

('a', 'd') ('b', 'e') ('c', 'f') ('a', 'g') ('b', 'h') ('c', 'i') ('d', 'j') ('e', 'k') ('f', 'l')

however i want my result to look like this:

('a', 'd') ('b', 'e') ('c', 'f') ('a', 'g') ('b', 'h') ('c', 'i') ('a', 'j') ('b', 'k') ('c', 'l') ('d', 'g') ('e', 'h') ('f', 'i') ('d', 'j') ('e', 'k') ('f', 'l') ('g', 'j') ('h', 'k') ('i', 'l')

What have I done wrong? Sorry for my bad English

Upvotes: 1

Views: 56

Answers (3)

Rohan Saxena
Rohan Saxena

Reputation: 3328

This is exactly the use case that zip was made for:

from itertools import combinations

a = [['a','b','c'], ['d','e','f'], ['g','h','i'], ['j','k','l']]

result = [list(zip(*x)) for x in combinations(a, 2)]

# If you want to flatten the result:
flat_result = [item for row in result for item in row]

print(flat_result)

result:

[[('a', 'd'), ('b', 'e'), ('c', 'f')],
 [('a', 'g'), ('b', 'h'), ('c', 'i')],
 [('a', 'j'), ('b', 'k'), ('c', 'l')],
 [('d', 'g'), ('e', 'h'), ('f', 'i')],
 [('d', 'j'), ('e', 'k'), ('f', 'l')],
 [('g', 'j'), ('h', 'k'), ('i', 'l')]]

flat_result:

[('a', 'd'), ('b', 'e'), ('c', 'f'), ('a', 'g'), ('b', 'h'), ('c', 'i'), ('a', 'j'), ('b', 'k'), ('c', 'l'), ('d', 'g'), ('e', 'h'), ('f', 'i'), ('d', 'j'), ('e', 'k'), ('f', 'l'), ('g', 'j'), ('h', 'k'), ('i', 'l')]

Or if you directly want to compute the flat version:

result = []
for x in combinations(a, 2):
    result += list(zip(*x))

Upvotes: 0

Christian Sloper
Christian Sloper

Reputation: 7510

Using combinations from itertools and some numpy slicing:

import numpy as np
import itertools


a = [['a','b','c'],['d','e','f'],['g','h','i'],['j','k','l']]
b = np.array(a)
m,n = b.shape

res = sorted([k for i in range(n) for k in itertools.combinations(b[:,i],2) ])

yields:

[('a', 'd'), ('a', 'g'), ('a', 'j'), ('b', 'e'), ('b', 'h'), ('b', 'k'), ('c', 'f'), ('c', 'i'), ('c', 'l'), ('d', 'g'), ('d', 'j'), ('e', 'h'), ('e', 'k'), ('f', 'i'), ('f', 'l'), ('g', 'j'), ('h', 'k'), ('i', 'l')]

Upvotes: 1

Stephen C
Stephen C

Reputation: 2036

How about this:

a = [['a','b','c'],['d','e','f'],['g','h','i'],['j','k','l']]

new_list = []   
for i in range(len(a)): # Loop over the first subgroup
    for j in range(i+1, len(a)): # Loop over the second subgroup
        for k in range(len(a[0])): # Loop through the elements of each subgroup
            new_list.append((a[i][k], a[j][k]))


new_list
[('a', 'd'), ('b', 'e'), ('c', 'f'),
 ('a', 'g'), ('b', 'h'), ('c', 'i'),
 ('a', 'j'), ('b', 'k'), ('c', 'l'),
 ('d', 'g'), ('e', 'h'), ('f', 'i'),
 ('d', 'j'), ('e', 'k'), ('f', 'l'),
 ('g', 'j'), ('h', 'k'), ('i', 'l')]

This could be more concise with a list-comprehension:

new_list = [(a[i][k], a[j][k]) for i in range(len(a)) 
            for j in range(i+1, len(a)) 
            for k in range(len(a[0])]

Upvotes: 1

Related Questions