Combinations of two inconsistent elements

Given a list, how can I get all combinations between two inconsistent elements?

For example, to enter [1, 2, 3, 4, 5] how can I get the output [(1,3), (1,4), (1,5), (2,4), (2,5), (3,5)] ?

I'm not interested in (1,2) , (2,3) , (3,4) or (4,5) , because they are consecutive (i.e. next to each other) in the list, but all that I interesting.

What is the most idiomatic way to do this in Python?

+5
source share
4 answers

Simple list comprehension:

 >>> lst = [1, 2, 3, 4, 5] >>> [(a, b) for i, a in enumerate(lst) for b in lst[i+2:]] [(1, 3), (1, 4), (1, 5), (2, 4), (2, 5), (3, 5)] 
+5
source

Here's a pretty β€œidiomatic” way to not use any modules that are more efficient than some other implementations, since every trip through the loop is used - not rejected.

 r = [1, 2, 3, 4, 5] c = [(r[i], r[j]) for i in range(len(r)-2) for j in range(i+2, len(r))] print(c) 

This gives

 [(1, 3), (1, 4), (1, 5), (2, 4), (2, 5), (3, 5)] 

It is not completely idiomatic, because it cyclically changes indexes, not values, but your restriction on the positions in the list, not the values, makes this quite necessary. If you need a generator, not a list, replace the outer brackets with parentheses.

+3
source

If you are interested in combinations with inconsistent numbers from the list:

 from itertools import combinations lst = [1, 2, 3, 4, 5] list(filter(lambda x: lst.index(x[1]) - lst.index(x[0]) > 1, combinations(lst,2))) [(1, 3), (1, 4), (1, 5), (2, 4), (2, 5), (3, 5)] 

This compares the indices of two numbers in a given combination and ensures that the difference in their indices is greater than 1.

Hope this helps.

+1
source

Here's a generalized solution for r-length combinations avoiding consecutive elements. It gets the entire combinations index for the corresponding shorter list, and then expands the indices of each combination. For example, for r = 3, any combination (x, y, z) turns into the used indices x + 0, y + 1, z + 2.

 from itertools import combinations def non_consecutive_combinations(lst, r): return [tuple(lst[j+i] for i, j in enumerate(combi)) for combi in combinations(range(len(lst)-r+1), r)] 

Demo for r = 2:

 >>> non_consecutive_combinations([1, 2, 3, 4, 5], 2) [(1, 3), (1, 4), (1, 5), (2, 4), (2, 5), (3, 5)] 

Demo for r = 3:

 >>> non_consecutive_combinations([1, 2, 3, 4, 5, 6, 7], 3) [(1, 3, 5), (1, 3, 6), (1, 3, 7), (1, 4, 6), (1, 4, 7), (1, 5, 7), (2, 4, 6), (2, 4, 7), (2, 5, 7), (3, 5, 7)] 

Simplified version for couples only:

 >>> [(lst[i], lst[j+1]) for i, j in combinations(range(len(lst)-1), 2)] [(1, 3), (1, 4), (1, 5), (2, 4), (2, 5), (3, 5)] 
+1
source

Source: https://habr.com/ru/post/1259325/


All Articles