#python-3.x #binance-api-client
Вопрос:
С помощью следующей команды я могу распечатать баланс своих активов из своего аккаунта binance ac.
Команда:
USDT_BAL = client.futures_account_balance(asset='USDT')
Возврат:
[{'accountAlias': 'sRuXXqTioCfWFz', 'asset': 'BNB', 'balance': '0.00000142', 'withdrawAvailable': '0.00000142', 'updateTime': 1621516315044}, {'accountAlias': 'sRuXXqTioCfWFz', 'asset': 'USDT', 'balance': '0.00000000', 'withdrawAvailable': '0.00000000', 'updateTime': 0}, {'accountAlias': 'sRuXXqTioCfWFz', 'asset': 'BUSD', 'balance': '0.00000000', 'withdrawAvailable': '0.00000000', 'updateTime': 0}]
Он возвращает остатки других активов, но мне нужен только баланс актива USDT. Как я мог бы отфильтровать переменную USDT_BAL для нее?
Комментарии:
1.
next((i['balance'] for i in USDT_BAL if i['asset'] == 'USDT'), None)
должно сработать. В противном случае он вернет баланс'USDT'
актива, если он существуетNone
.2. Это работает, спасибо.
3. Не могли бы вы объяснить, как это работает?
4. Я добавил это в качестве ответа и рассказал немного подробнее.
Ответ №1:
Расширяю свой комментарий:
У тебя есть list
оф dict
. list
доступ осуществляется с помощью итераций ( for
циклов) или индексов. my_list[0]
и т.д..
dict
доступ может быть также выполнен итерацией, но большим преимуществом является доступ с ключом. my_dict['some_key']
и т.д..
Python упростил способы выполнения общих list
и dict
часто называемых «постижений».
Таким list
образом, понимание чего-то вроде:
my_list = []
for i in range(10):
my_list.append(i)
Может быть записано как
my_list = [i for i in range(10)]
То, что я вам дал, не обязательно является list
пониманием, но следует той же идее. Это называется «генераторным выражением». Разница в том, что он генерирует некоторые выходные данные, когда вы повторяете его, но его выходные данные в целом не представлены в виде какой-либо встроенной коллекции ( list
или dict
).
Причина, по которой это имеет смысл в данном контексте, заключается в:
- Мне нужно повторить
list
, чтобы найтиdict
правильный'asset'
ключ. - Я ожидаю, что это произойдет только в одном случае, поэтому я забочусь только о первом случае.
Итак, чтобы разбить его, у вас есть выражение генератора:
(i['balance'] for i in USDT_BAL if i['asset'] == 'USDT')
Что примерно эквивалентно.
def my_gen():
for i in USDT_BAL:
if i['asset'] == 'USDT':
yield i['balance']
Или, если вы не знакомы с генераторами и хотели бы, чтобы это было list
:
my_list = []
for i in USDT_BAL:
if i['asset'] == 'USDT':
my_list.append(i['balance'])
Так что теперь вы видите, что у нас есть проблема.
Если у нас есть это как list
понимание, то оно в форме а list
с одним элементом.
print(my_list) # ['0.00000000']
Мы могли бы получить к нему доступ, my_list[0]
но это выглядит уродливо, ИМО, но для каждого это свое.
Так вот в чем заключается next
функция. Согласно документам next
, вызывает __next__
метод на итераторе (которым является генератор) и в основном продвигает генератор. Так что , если бы наш генератор должен был производить 1
, то 2
тогда 3
вызов next(my_gen)
произвел 1
бы, затем вызов его снова произвел 2
бы и так далее.
Поскольку я ожидаю, что это выражение генератора произведет только 1 элемент, я вызываю его только один раз. Присвоение ему значения по умолчанию None
означает, что если оно пустое, вместо того, чтобы вызывать ошибку, которую оно вызовет None
.
Так:
next((i['balance'] for i in USDT_BAL if i['asset'] == 'USDT'), None)
создает генератор , который повторяет ваш list
, создает только 'balance'
ключ dict
s, 'asset'
ключ которого равен 'USDT'
, и вызывает next
этот генератор по умолчанию None
.