Python filter string - python-3.x

With the following command i can print the balance of my assets from my binance ac.
Command:
USDT_BAL = client.futures_account_balance(asset='USDT')
Return:
[{'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}]
It returns the balances of other assets, but i only need the balance of the USDT asset. How could I filter the USDT_BAL variable for it?

Expanding on my comment:
You have a list of dict. list access is done by iteration (for loops) or by indexes. my_list[0], etc..
dict access can, also done by iteration, but a big benefit is keyed access. my_dict['some_key'], etc..
Python has simplified ways to do common list and dict building commonly called "comprehensions".
So a list comprehension for something like:
my_list = []
for i in range(10):
my_list.append(i)
Could be written as
my_list = [i for i in range(10)]
What I gave you isn't necessarily a list comprehension but follows the same idea. It's called a "generator expression". The difference is it generates some output when you iterate over it but it's output as a whole isn't in the form of some built-in collection (list or dict).
The reason it makes sense in this context is:
I need to iterate over the list to find dict with the correct 'asset' key.
I expect there is only one occurrence of this so I care only about the first occurrence.
So to break it down you have a generator expression:
(i['balance'] for i in USDT_BAL if i['asset'] == 'USDT')
Which is roughly equivalent to.
def my_gen():
for i in USDT_BAL:
if i['asset'] == 'USDT':
yield i['balance']
Or if you're not familiar with generators and would like it as a list:
my_list = []
for i in USDT_BAL:
if i['asset'] == 'USDT':
my_list.append(i['balance'])
So now you can see we have a problem.
If we have it as a list comprehension it's in the form of a list with one element.
print(my_list) # ['0.00000000']
We could access it with my_list[0] but that looks ugly IMO but to each it's own.
So that's where the next function comes in.
According to the docs next calls the __next__ method on an iterator (which a generator is) and basically advances the generator.
So if our generator were to produce 1 then 2 then 3, calling next(my_gen) would produce 1 then calling it again would produce 2 and so on.
Since I expect this generator expression to only produce 1 item, I only call it once. Giving it a default of None means, if it's empty, rather than raising an error it will produce None.
So:
next((i['balance'] for i in USDT_BAL if i['asset'] == 'USDT'), None)
creates a generator that iterates over your list, only produces the 'balance' key of dicts who's 'asset' key equals 'USDT' and calls next on that generator with a default of None.

Related

Generate a list of strings from another list using python random and eliminate duplicates

I have the following list:
original_list = [('Anger', 'Envy'), ('Anger', 'Exasperation'), ('Joy', 'Zest'), ('Sadness', 'Suffering'), ('Joy', 'Optimism'), ('Surprise', 'Surprise'), ('Love', 'Affection')]
I am trying to create a random list comprising of the 2nd element of the tuples (of the above list) using the random method in such a way that duplicate values appearing as the first element are only considered once.
That is, the final list I am looking at, will be:
random_list = [Exasperation, Suffering, Optimism, Surprise, Affection]
So, in the new list random_list, strings Envy and Zest are eliminated (as they are appearin the the original list twice). And the process has to randomize the result, i.e. with each iteration would produce a different list of Five elements.
May I ask somebody to show me the way how may I do it?
You can use dictionary to filter the duplicates from original_list (shuffled before with random.sample):
import random
original_list = [
("Anger", "Envy"),
("Anger", "Exasperation"),
("Joy", "Zest"),
("Sadness", "Suffering"),
("Joy", "Optimism"),
("Surprise", "Surprise"),
("Love", "Affection"),
]
out = list(dict(random.sample(original_list, len(original_list))).values())
print(out)
Prints (for example):
['Optimism', 'Envy', 'Surprise', 'Suffering', 'Affection']

Flatten List of Lists Recursively

Can someone illustrate or decompose how this recursive function is executed
def flatten(S):
if S == []:
return S
if isinstance(S[0], list):
return flatten(S[0]) + flatten(S[1:])
return S[:1] + flatten(S[1:])
s=[[1,2],[3,4]]
print("Flattened list is: ",flatten(s))
How could I trace the execution of this algorithm?
Ok so this is a recursive function as you have stated. It is a mostly 'look at the next element and decide what to do with it' method. It is started with the base case.
if S == []:
return S
So this makes sense. You have an empty list, so you would expect to get back an empty list, it's flat.
if isinstance(S[0], list):
return flatten(S[0]) + flatten(S[1:])
Next is the first 'look at the next element, decide what to do', if I receive a list and at the first element there is a list, I will get the program to run this same flattening method on the first element.
But then comes the rest of the list, we don't know if that is flat so I will be doing the same thing for that calling flatten on that as well.
When this returns they should both be flat lists. Adding two lists just joins them together into a new list so this would be returned up a level to the previous call of the recursive method or return to the user.
return S[:1] + flatten(S[1:])
From before we know that the first element of the list is not a list as the if statement was if isinstance(S[0], list) so this is just taking a list with the first element stored in it and just like before running flatten on the rest of the list as we don't know whether the rest of the list is flat or not.
As for tracing, if you don't have Pycharm or pdb is to complex for you. Throw in some prints within each of the if statements. Don't be shy, you're the one that's going to read them. do a print(f"First element was a list: {S[0]}, {S[1:]}") that will be fine if you're a beginner dealing with such a small amount of code. Otherwise try PDB or such.

Printing a list method return None

I am an extremely begginer learning python to tackle some biology problems, and I came across lists and its various methods. Basically, when I am running print to my variable I get None as return.
Example, trying to print a sorted list assigned to a variable
list1=[1,3,4,2]
sorted=list1.sort()
print(sorted)
I receive None as return. Shouldn't this provide me with [1,2,3,4]
However, when printing the original list variable (list1), it gives me the sorted list fine.
Because the sort() method will always return None. What you should do is:
list1=[1,3,4,2]
list1.sort()
print(list1)
Or
list1=[1,3,4,2]
list2 = sorted(list1)
print(list2)
You can sort lists in two ways. Using list.sort() and this will sort list, or new_list = sorted(list) and this will return a sorted list new_list and list will not be modified.
So, you can do this:
list1=[1,3,4,2]
sorted=sorted(list1)
print(sorted)
Or you can so this:
list1=[1,3,4,2]
list1.sort()
print(list1)

Python- If condition for a variable True, execute function assigning new variable until False

I've not ever encountered this type of situation in a Python for loop before.
I have a dictionary of Names (key) and Regions (value). I want to match up each Name with two other names. The matched name cannot be themselves and reversing the elements is not a valid match (1,2) = (2,1). I do not want people from the same Region to be matched together though (unless it becomes impossible).
dict = {
"Tom":"Canada",
"Jerry":"USA",
"Peter":"USA",
"Pan":"Canada",
"Edgar":"France"
}
desired possible output:
[('Tom','Jerry'),('Tom','Peter'),('Jerry','Pan'),('Pan','Peter'),('Edgar','Peter'),('Edgar','Jerry')]
Everyone appears twice, but Jerry and Peter appears more in order for Edgar to have 2 matches with Names from a different region (Jerry and Peter should be chosen randomly here)
Count: Tom: 2, Jerry: 3, Peter: 3, Pan: 2, Edgar: 2
My approach is to convert the names into a list, shuffle them, then create tuple pairs using zip in a custom function. After the function is complete. I use a a for to check for pairings from the same region, if a same pairing region exists, then re-run the custom function. For some reason, when I print the results, I still see pairings between the same regions. What am I missing here?
import random
names=list(dict.keys())
def pairing(x):
random.shuffle(x)
#each person is tupled twice, once with the neighbor on each side
pairs = list(zip(x, x[1:]+x[:1]))
return pairs
pairs=pairing(names) #assigns variable from function to 'pairs'
for matchup in pairs:
if dict[matchup[0]]==dict[matchup[1]]:
break
pairing(names)
pairs=pairing(names)
for matchup in pairs:
print(matchup[0] ,dict[matchup[0]] , matchup[1] , dict[matchup[1]])
Just looking at it, something is clearly broken in the for loop, please help!
I've tried while rather than if in the for loop, but it did not work.
from itertools import combinations
import pandas as pd
import random
dict={'your dictionary'}
#create function to pair names together
def pairing(x):
random.shuffle(x)
#each person is tupled twice, once with the neighbor on each side
pairs = list(zip(x, x[1:]+x[:1]))
for matchup in pairs:
if dict[matchup[0]]==dict[matchup[1]]: #if someone's gym matches their opponent's gym in dictionary, re-run this function
return pairing(x)
return pairs
pairs=pairing(names)
for matchup in pairs:
print(matchup[0] ,dict[matchup[0]] , matchup[1] , dict[matchup[1]])
The trick is to return pairing(x) inside the custom function. This will return new pairings if any elements in the tuple share the same value in the dictionary. If inside the if statement, you go pairing(x) then return pair, it'll return the original tuple list which contains duplicates.

comprehensive dict with multiple or repeated values in python3

I have an extensive list with tuples of pairs. It goes like this:
travels =[(passenger_1, destination_1), (passenger_2, destination_2),(passenger_1, destination_2)...]
And so on. Passengers and destinations may repeat and even the same passenger-destination tuple may repeat.
I want to make a comprehensive dict thay have as key each passenger and as value its most recurrent destination.
My first try was this:
dictionary = {k:v for k,v in travels}
but each key overwrites the last. I was hoping to get multiple values for each key so then i could count for each key. Then I tried like this:
dictionary = {k:v for k,v in travels if k not in dictionary else dictionary[k].append(v)}
but i can't call dictionary inside its own definition. Any ideas on how can i get it done? It's important that it's done comprehensively and not by loops.
That is how it can be done with for loop:
result = dict()
for passenger, destination in travels:
result.setdefault(passenger, list()).append(destination)
result is a single dictionary where keys are passengers, values are lists with destinations.
I doubt you can do the same with a single dictionary comprehesion expression since inside comprehension you can just generate elements but can not freely modify them.
EDIT.
If you want to (or have to) use comprehension expression no matter what then you can do it like this (2 comprehensions and no explicit loops):
result = {
passenger: [destination_
for passenger_, destination_
in travels
if passenger_ == passenger]
for passenger, dummy_destination
in travels}
This is a poor algorithm to get what you want. Its efficiency is O(n^2) while efficiency of the first method is O(n).

Resources