# Python Combinatory Algorithm - A Binomial Coefficient application with n mutable and k fixed to 2

This question came from a real use case. I had a data frame with different columns each one containing data from a data source and I wanted to design a hypothesis test to prove or not if the data had the same mean. So I had to compute the Kolmogorov-Smirnov test for each couple of columns.

Now the problem can be generalized to any combinatory task.

It follows that I had to implement a Binomial Coefficient like

$$\binom{n}{k}$$

Where n is the number of columns

and k is = 2

My question is: if exists a more efficient way to apply a function on permutated samples taken from a list? And how to do this permutation eg. Given a func and a list [a,b,c,d]

func(a,b)
func(a,c)
func(a,d)
func(b,c)
func(b,d)
func(c,d)


I created an algorithm to solve this issue, but I am wondering if there is a better way to do that in Python.

In my algorithm, I simply multiply each n element in an explanatory array with another element i of the same array, with n!=i, instead of computing the statistical test.

to_do=[1,2,3,4,5]
#done will store information on the elements already combined
done=[]
#j will store information on the results of the combination
j=[]

#iterating over the to_do array
for n in to_do:

#checking if we already computed the n element
if n not in done:
print(n)
#taking another i element from the array
#where n!=i
for i in to_do:
print(i)
#if the condition is satisfied
if i!=n:
#combine the two elements
m=n*i

#append the result on the "j" array
j.append(m)
#updating the array with the "done" elements
done.append(n)

print(len(done))
print(len(j))

• Unclear. What exactly is the input, what exactly is the output? Do you just want itertools.permutations(to_do, 2)? – superb rain Dec 27 '20 at 21:17
• The input is the array ´to_do´ and then each element of the array is multiplied with another one and this operation should be done for each element. – Andrea Ciufo Dec 28 '20 at 9:42
• I read the documentation, how can I avoid to repeat an operation when I have to permutate like in the documentation a list of 4 elements [ABCD] and I need only AB and not BA (or viceversa). I tried to fix this issue with the done array in my code – Andrea Ciufo Dec 28 '20 at 10:01
• Well your own code does both AB and BA. Are you saying your code isn't correct and thus your question is off-topic? – superb rain Dec 28 '20 at 15:37

If you just want the length of the list, your code can be reduced to one line:

result = len(to_do) * (len(to_do) - 1)


Also, you're comments are, at the very least, excessive. You should really only use comments to explain a design choice or a complicated equation/algorithm. Comments like #if the condition is satisfied just clutters your code.

As explained in a comment, actual computations need to be made. This can be done using itertools.permutations.

import itertools
from typing import List

def func(nums: List[int]) -> List[int]:

return list(set(
x * y for x, y in itertools.permutations(nums, 2)
))


While this doesn't avoid the extra computations, it's a short and sweet solution. And below is how you would use it:

to_do = [1, 2, 3, 4, 5]
func(to_do)

• Thank you the point about the comment is very useful, the output as I commented above is to multiply each element of the list with another one and this should be done for all the elements, except for the multiplication of the element ´i´ with itself. – Andrea Ciufo Dec 28 '20 at 9:45
• @AndreaCiufo Please see my edited answer. – Linny Dec 28 '20 at 12:51
• what does it mean -> List[int] it's the first time that I see it in the function signature? – Andrea Ciufo Jan 2 at 18:12
• @AndreaCiufo It means that the function returns a list of integers. Take a look at the python docs regarding type hints – Linny Jan 2 at 20:01

My question is: if exists a more efficient way to apply a function on permutated samples taken from a list? And how to do this permutation eg. Given a func and a list [a,b,c,d]

func(a,b)

func(a,c)

func(a,d)

func(b,c)

func(b,d)

func(c,d)

It seems that you are looking for combinations rather than permutations. In that case, use itertools.combinations:

from itertools import combinations

for x, y in combinations(['a', 'b', 'c', 'd'], 2):
print(x, y)


It prints:

a b
a c
a d
b c
b d
c d


Using itertools.combinations in your example:

from itertools import combinations

todo = [1, 2, 3, 4, 5]
j = [x * y for x, y in combinations(todo, 2)]