Эффективный подход
Это очень быстро выполнит поиск допустимых триплетов в вашем списке ввода. Надеюсь, это также довольно ясно и просто. Но это нормализует порядок пар (т.е. размещает каждую пару в алфавитном порядке). Дайте мне знать, если это проблема.
pairs = ['BCH/BTC','BCH/ETH','DASH/USD','BTC/USDT','ETH/BTC']
# make a dict of all alphabetically higher partners for each symbol
pair_dict = {}
for pair_str in pairs:
p0, p1 = sorted(pair_str.split('/'))
# create sets if needed, then record this pair
pair_dict.setdefault(p0, set())
pair_dict.setdefault(p1, set())
pair_dict[p0].add(p1)
# process the dict, finding all valid triplets of pairs
triplets = list()
for p0 in pair_dict:
p0_pairs = pair_dict[p0]
for p1 in p0_pairs:
p1_pairs = pair_dict[p1]
for p2 in p1_pairs:
if p2 in p0_pairs:
# there's a chain from p0 to p1 to p2 to p0;
# add them to the list of triplets
triplets.append((p0, p1, p2))
final = [[p0+'/'+p1, p1+'/'+p2, p2+'/'+p0] for p0, p1, p2 in triplets]
print(final)
# [['BCH/BTC', 'BTC/ETH', 'ETH/BCH']]
Я использовал наборы вместо списков в pair_dict
, потому что они быстрее выполняют поиск и устраняют любые дубликаты. Кроме того, for p0 in pair_dict
совпадает с for p0 in pair_dict.keys()
, а for p0, p1, p2 in triplets
означает «взять каждый элемент из triplets
и разбить его на переменные p0
, p1
и p1
».
Упрощенный подход
Если вы ищете что-то более простое (хотя и менее эффективное), вы можете попробовать код ниже.
Обратите внимание, что это зависит от нескольких интересных вещей. 1. Если вы сортируете монеты в каждой паре, а также сортируете пары в каждом триплете, то вам гарантированно, что каждый действительный триплет будет выглядеть как ['a / b', 'a / c', 'b / c'], где a, b и c - разные монеты в алфавитном порядке. 2. Если вы передадите отсортированный список в itertools.combinations()
, то триплеты, которые он выдает , также будут отсортированы .
Таким образом, приведенный ниже код сортирует внутри каждой пары, затем сортирует список пар, а затем использует itertools.combinations()
для получения отсортированных триплетов. Затем он проверяет, соответствует ли какой-либо из этих триплетов требуемому шаблону.
import itertools
# added another pair to make it more interesting
pairs = ['BCH/BTC','BCH/ETH','DASH/USD','BTC/USDT','ETH/BTC','USDT/ETH']
pairs_normalized = sorted(sorted(pair.split('/')) for pair in pairs)
triplets = [
(p1, p2, p3)
for p1, p2, p3 in itertools.combinations(pairs_normalized, 3)
# look for ['a/b', 'a/c', 'b/c'] pattern
if p1[0] == p2[0] and p1[1] == p3[0] and p2[1] == p3[1]
]
output = [['/'.join(p) for p in triplet] for triplet in triplets]
print(output)
# [['BCH/BTC', 'BCH/ETH', 'BTC/ETH'], ['BTC/ETH', 'BTC/USDT', 'ETH/USDT']]