What is the more elegant way of finding combinations in a list?

  • A+
Category:Languages

I came up with this algorithm to find triplets of pairs (I call them trairs), the criteria is that all 3 elements (coins), and only the 3, must be present in all 3 pairs.

However, it is probably possible to solve the same problem in a more elegant way. For instance, I am indexing all the loops, which makes it look extra complicated. Also, there is a break there that makes me uncomfortable!

The input data is pairs, it is a list of str:
Eg. pairs = ['BCH/BTC','BCH/ETH','DASH/USD','BTC/USDT','ETH/BTC']

The wanted output is a list of list of strings:
Eg. trair = [['BCH/BTC','BCH/ETH','ETH/BTC]]

def find_trairs(exchange):     ''' Find possible triplets of pairs (trairs) that can be traded for unbalance.      Example of trairs:     'ETC/BTC' 'ETC/ETH' 'ETH/BTC'     'BCH/BTC' 'BCH/EUR' 'BTC/EUR'      '''     exchange_pairs = exchange.symbols #loads all pairs from the exchange.     pairs = list(filter(lambda x: not '.d' in x, exchange_pairs)) #filters off      #the darkpool pairs.      pair = ['', '', '']     coin = ['', '', '']     trair = []      #Semi-optimized loop to look for triplece of pairs.     #Example:['BCH/BTC', 'BCH/EUR', 'BTC/EUR']     for i in range(len(pairs)-3):         #not all coins are 3 digits long, we must find the slash that separetes         #each coin in order to have a robust algorithm.         slash_position = pairs[i].find('/')          coin[0] = pairs[i][0:slash_position]         coin[1] = pairs[i][slash_position+1:]         for j in range(i+1, len(pairs)-2):             if (coin[0] in pairs[j]):                 slash_position = pairs[j].find('/')                  coin[2] = pairs[j][slash_position+1:]                 for k in range(j+1, len(pairs)-1):                     if coin[1] in pairs[k] and coin[2] in pairs[k]:                         trair.append([pairs[i], pairs[j], pairs[k]])                         break      return trair 

Any hints or comments?

 


Use itertools permutations, with filtering the results, and elimination of duplicates:

import itertools  currency_pairs = ['BCH/BTC', 'BCH/ETH', 'DASH/USD', 'BTC/USDT', 'ETH/BTC'] set_triplets = set() for triplet in itertools.permutations(currency_pairs, 3):     c1, c2 = triplet[0].split('/')     if (c1 in triplet[1] or c1 in triplet[2]) and (c2 in triplet[1] or c2 in triplet[2]):         set_triplets.add(tuple(sorted(triplet))) for triplet in set_triplets:     print(triplet) 

output:

('BCH/ETH', 'BTC/USDT', 'ETH/BTC')  ('BCH/BTC', 'BCH/ETH', 'BTC/USDT') ('BCH/BTC', 'BCH/ETH', 'ETH/BTC') 

Please note that the ordering of the currency pairs in a triplet is lexicographically ascending, do not expect the first pair to always be the link between the two others.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: