#python #dictionary
#python #словарь
Вопрос:
Я ищу совпадения между цитатами CoinBuy и CoinSell.
Я смог подсчитать экземпляры, и когда один или несколько из них появляются 6 раз, я знаю, что у меня есть совпадение по всем 6 параметрам. И это здорово.
Но когда я изо всех сил пытаюсь соединить ‘CoinBuy’ с ‘coinsell’s
all_options = [
{'CoinBuy': 1, 'Base': 'DEXE', 'Quote': {'USDT', 'ETH', 'BUSD'}},
{'CoinBuy': 2, 'Base': 'BOND', 'Quote': {'USDT', 'BTC', 'BUSD'}},
{'CoinBuy': 3, 'Base': 'STX', 'Quote': {'USDT', 'BTC', 'BUSD'}},
{'CoinSell': 1, 'Base': 'NAS', 'Quote': {'ETH', 'BTC'}},
{'CoinSell': 2, 'Base': 'CHESS', 'Quote': {'USDT', 'BTC', 'BUSD'}},
{'CoinSell': 3, 'Base': 'REP', 'Quote': {'USDT', 'ETH', 'BTC', 'BUSD'}}
]
Ожидаемый результат:
Matches
CoinBuy 1 amp; CoinSell 3 in common 'ETH'
CoinBuy 2 amp; CoinSell 2 in common 'USDT', 'BTC', 'BUSD'
CoinBuy 3 amp; CoinSell 1 in common 'BTC', 'BUSD'
Комментарии:
1. Вы ищете совпадения только между определенными парами? Например, вас волнует, что CoinBuy 1 и CoinSell 2 -> USDT, BUSD?
2. Вы можете использовать set intersection для поиска общих элементов в
Quote
.3. нет, они могут совпадать с любой комбинацией
4. Тогда почему этой пары нет в вашем ожидаемом выводе?
5. Составьте список всех покупок, другой список всех продаж. Затем используйте вложенный цикл для сравнения каждой покупки с каждой продажей. Если есть какие-либо общие кавычки, выведите совпадение.
Ответ №1:
Это вполне возможно:
dx = dict()
for opt in all_options:
for quote in opt.get('Quote'):
ls = dx.get(quote, [])
ls.append(opt)
dx[quote] = ls
commonalities = {}
for exchange, opts in dx.items():
for i in range(len(opts)):
left = opts[i]
for j in range(i 1,len(opts)):
right = opts[j]
buy_index = sell_index = None
if 'CoinBuy' in left and 'CoinSell' in right:
buy_index = left.get('CoinBuy')
sell_index = right.get('CoinSell')
elif 'CoinBuy' in right and 'CoinSell' in left:
buy_index = right.get('CoinBuy')
sell_index = left.get('CoinSell')
# Both other cases are invalid pairs
if buy_index and sell_index:
commonality = commonalities.get((buy_index, sell_index), [])
commonality.append(exchange)
commonalities[(buy_index, sell_index)] = commonality
for commonality, exchanges in commonalities.items():
buy_index, sell_index = commonality
excs = ", ".join((f"'{e}'" for e in exchanges))
print(f"CoinBuy {buy_index} amp; CoinSell {sell_index} in common {excs}")
Тем не менее, вышесказанное довольно неудобно и довольно грубо. Основной алгоритм:
- Переверните структуру данных, чтобы создать словарь, который использует exchange в качестве ключа, а ваши параметры — в качестве значений. Таким образом, вы знаете для каждого обмена, какие параметры относятся.
- Для каждого обмена мучительно создавайте пары между вариантами, если каждая сторона пары имеет противоположные типы (покупка против продажи).
- Переверните индексацию еще раз, выведя индексы сопряжения в качестве ключа и добавив к каждому обмену тот же ключ.
- Просмотрите список индексов сопряжения и распечатайте все совпадающие обмены.
Вывод выглядит следующим образом:
>>> for commonality, exchanges in commonalities.items():
... buy_index, sell_index = commonality
... excs = ", ".join((f"'{e}'" for e in exchanges))
... print(f"CoinBuy {buy_index} amp; CoinSell {sell_index} in common {excs}")
...
CoinBuy 1 amp; CoinSell 2 in common 'USDT', 'BUSD'
CoinBuy 1 amp; CoinSell 3 in common 'USDT', 'BUSD', 'ETH'
CoinBuy 2 amp; CoinSell 2 in common 'USDT', 'BUSD', 'BTC'
CoinBuy 2 amp; CoinSell 3 in common 'USDT', 'BUSD', 'BTC'
CoinBuy 3 amp; CoinSell 2 in common 'USDT', 'BUSD', 'BTC'
CoinBuy 3 amp; CoinSell 3 in common 'USDT', 'BUSD', 'BTC'
CoinBuy 1 amp; CoinSell 1 in common 'ETH'
CoinBuy 2 amp; CoinSell 1 in common 'BTC'
CoinBuy 3 amp; CoinSell 1 in common 'BTC'
Единственная причина, по которой я изложил это, а не (более уместно) позволил вам сначала попробовать, заключается в том, что интуиция для изменения индексации не является обычной, но она может значительно упростить такую обработку. Кроме того, это демонстрирует, насколько неудобна ваша исходная структура данных (почему ключи ‘CoinBuy’ и ‘CoinSell’, а не значения другого ключа, скажем, ‘transaction_type’?) и сколько дополнительной логики это в конечном итоге заставляет вас.
Тем не менее, это решение вряд ли выдержит большое количество сравнений (учитывайте количество вложенных циклов). Вероятно, вам захочется подумать о том, как вы хотите преобразовать исходную структуру данных во что-то, что более легко отвечает на вопрос, который вы ищете. Или поместите все это в базу данных и используйте соответствующий запрос.