add current position+1 or -1 dict value to dict python - python-3.x

for example:
s = 'abc'
number = 1
I want to write a function that return a dict like {'a': {'a', 'b'}, 'b': {'a', 'b', 'c'}, 'c': {'b', 'c'}}
number determine how many adjacent letters next to the current key.
def test(s : str, num : int) -> {str:{str}}:
dict = {}
for word in s:
dict[word] = word
return dict
i can only write one return the same key and value. any suggestions?

Try something like:
>>> s='abc'
>>> n=1
>>> {c:{e for e in[s[i-n:i],c,s[i+1:i+1+n]] if e} for i, c in enumerate(s)}
{'a': {'a', 'b'}, 'b': {'a', 'b', 'c'}, 'c': {'b', 'c'}}

Related

Python3 for loop over a dict

I am trying to get all the values individually for each asset (BCHUSD and TRXUSD).
What I want to do is something like this:
BCHUSD a = 301.340000 b = 301.160000 c = 301.280000
TRXUSD a = 0.0609450 b = 0.0609440 c = 0.0609540
Could someone tell me how I can do it please?
Regards!
import requests
import json
while True:
req = requests.get('https://api.kraken.com/0/public/Ticker?pair=BCHUSD,TRXUSD,XRPUSD')
print(req)
<Response [200]>
print(type(req))
<class 'requests.models.Response'>
obj = req.json()
print(type(obj))
<class 'dict'>
for k, v in obj.items():
if type(v) is dict and k:
for nk, nv in v.items():
print(nk, nv)
BCHUSD {'a': ['298.240000', '11', '11.000'], 'b': ['298.040000', '3', '3.000'], 'c':
['299.000000', '0.89507885'], 'v': ['38.42175237', '5614.56089299'], 'p':
['300.890848', '277.650439'], 't': [24, 2314], 'l': ['299.000000', '260.000000'], 'h':
['302.390000', '309.900000'], 'o': '299.000000'}
TRXUSD {'a': ['0.0608250', '4881', '4881.000'], 'b': ['0.0607820', '40500',
'40500.000'], 'c': ['0.0608630', '81.94337742'], 'v': ['21067.61432979',
'9622286.56922629'], 'p': ['0.0610566', '0.0589675'], 't': [25, 1729], 'l':
['0.0608630', '0.0562060'], 'h': ['0.0612840', '0.0618410'], 'o': '0.0611130'}
XXRPZUSD {'a': ['0.69018000', '666', '666.000'], 'b': ['0.69000000', '42829',
'42829.000'], 'c': ['0.69022000', '358.00000000'], 'v': ['287549.02071579',
'27810492.67564827'], 'p': ['0.69737332', '0.65981291'], 't': [429, 10340], 'l':
['0.69000000', '0.62229000'], 'h': ['0.70386000', '0.72105000'], 'o': '0.69935000'}
I think the following could help you as a starting point:
response_json = {
"title": "name",
"abc": {'a': [1,2,3], "b": [2,3,4]},
"ohter_stuff": "xxx",
"xyz": {'a': [10, 20 ,30], "b": [20, 30, 40]}
}
# select relevant key value pairs
data = {
key: value for key, value in response_json.items()
if isinstance(value, dict)
}
# get the inner subdict index length
length = len(data['abc']['a'])
# get the inner subdict keys
items = list(data['abc'].keys())
# loop and print
for index in range(length):
for name, subdict in data.items():
# join the items at index pairs into a string
index_items = " ".join(
f"{item} = {subdict[item][index]}"
for item in items
)
print(name, index_items)
This is a pure standard library python solution. If you can install other libraries, I would recommend to have a look into pandas.

How to find frequency of values in a list of lists and combine with another existing list by common value?

I have a nested list of music artists comprised of user inputs, lets say:
artists_list = [['A', 'B', 'C'],
['A', 'C', 'B'],
['B', 'A', 'D']]
I've also managed to create a separate list, based on order of input (not alphabetically), that assigns a genre to each unique artist in the above list:
artist_genre_list = [['A', 'Rock'],
['B', 'Rap'],
['C', 'Rock'],
['D', 'Blues']]
How do I combine these two to make either a master list or dictionary including the frequency count similar to:
master_list = [['A', 'Rock', 3],
['B', 'Rap', 3],
['C', 'Rock', 2],
['D', 'Blues', 1]]
master_dict = {'A': {
'Genre': 'Rock',
'Frequency': 3},
'B': {
'Genre': 'Rap',
'Frequency': 3},
'C': {
'Genre': 'Rock',
'Frequency': 2},
'D': {
'Genre': 'Blues',
'Frequency': 1}
}
The order doesn't necessarily have to be alphabetical. Here is a sample of what I'm doing to create the first two lists:
# Counters
count = 1
new_artist_counter = 0
# Generate Lists
artists_input_list = []
aux_artists_list = []
aux_genre_list = []
aux_artists_genre_list = []
def merge(aux_artists_list, aux_genre_list):
merged_list = [[aux_artists_list[i], aux_genre_list[i]] for i in range(0,
len(aux_artists_list))]
return merged_list
while count < 4:
# Inputs
a1_in = str(input("Artist 1: "))
a2_in = str(input("Artist 2: "))
a3_in = str(input("Artist 3: "))
artists_input_list.append([a1_in, a2_in, a3_in])
# Determines if new unique artist has been added and asks for it's genre
while new_artist_counter < len(artists_input_list):
for entry in artists_input_list:
for artist in entry:
if artist not in aux_artists_list:
aux_artists_list.append(artist)
genre_input = input("What is "+artist+"'s genre? ")
aux_genre_list.append(genre_input)
else: continue
new_artist_counter += 1
aux_artists_genre_list = merge(aux_artists_list, aux_genre_list)
# Counter updates
count += 1
print(artists_input_list)
print(aux_artists_genre_list)
This is what I came up with. It first flattens your artist list, gets the frequencies of each item in the list then combines it with your genre list
from itertools import groupby, chain
import pprint
artists_list = [
['A', 'B', 'C'],
['A', 'C', 'B'],
['B', 'A', 'D']
]
artist_genre_list = [
['A', 'Rock'],
['B', 'Rap'],
['C', 'Rock'],
['D', 'Blues']
]
frequencies = {
key: len(list(value)) for key,
value in groupby(sorted(chain.from_iterable(artists_list)))
}
frequency = [{
letter: {
'Genre': genre,
'Frequency': next((freq
for key, freq in frequencies.items() if key is letter), 0)
}
}
for letter, genre in artist_genre_list
]
pprint.pprint(frequency)
I used pprint just to make the output tidier, which shows as
[{'A': {'Frequency': 3, 'Genre': 'Rock'}},
{'B': {'Frequency': 3, 'Genre': 'Rap'}},
{'C': {'Frequency': 2, 'Genre': 'Rock'}},
{'D': {'Frequency': 1, 'Genre': 'Blues'}}]

The question given to me was to create a new dictionary with inverted key value pairs from the original dictionary

create a new dictionary(new_dict) with inverted key-value pairs from the original dictionary (my_dict)
def invert(dic_t):
new_dict={}
for key,value in dic_t.items():
new_dict[key]=value
new_dict[value]=key
return new_dict
my_dict = {
"A": "B",
"C": "D",
"E": "F"
}
print(invert(my_dict))
Output:
{'A': 'B', 'B': 'A', 'C': 'D', 'D': 'C', 'E': 'F', 'F': 'E'}
I am new to python so any help would be useful
What you are doing is correct, you just have to remove the line new_dict[key]=value as this represents the same old dictionary
def invert(dic_t):
new_dict={}
for key,value in dic_t.items():
# new_dict[key]=value
new_dict[value]=key
return new_dict
Also, you can use dictionary comprehension if you are looking for an one-line answer!
def invert(dict_t):
return {v:k for k, v in dict_t.items()}

nested dictionary based on 3 dataframe columns

im trying to build a nested dictionary based on 3 pandas df columns:
dataframe: stops
columns: 'direction' (1-2) ,'stop_num'(1-23 if the direction is 1 and 100-2300 if direction is 2),'name_eng'
what i was trying to do is:
dct = {x: {y:z} for x, y, z in zip(stops['direction'],stops['name_eng'],stops['stop_num'])}
the result i get is a nested dictionary indeed but for unknown reason i get only the last value in y:z so the dictionary look like:
{1:{1:'aaa'},'2:{100:'bbb'}}
any idea what am i doing wrong?
what i need is a nested dictionary with two dictionaries for each direction.
thanks!
Imagine your columns are:
1 a 1a
1 b 1b
2 a 2a
2 b 2b
Now, try your code:
>>> {x: {y:z} for x, y, z in zip([1,1,2,2], ['a', 'b', 'a', 'b'], ['1a', '1b', '2a', '2b'])}
{1: {'b': '1b'}, 2: {'b': '2b'}}
You have a loop over the tuples: (1, 'a', '1a'), (1, 'b', '1b'), (2, 'a', '2a'), (2, 'b', '2b').
The first element of the tuple is the "main" key of your dictionary. Thus, the dict is {1: {'a':'1a'}} after the first tuple.
Then comes (1, 'b', '1b'). The value of the main key 1 is overwritten and the dict becomes: {1: {'b':'1b'}}.
The next steps are: {1: {'b':'1b'}, 2: {'a': '2a'}} and {1: {'b': '1b'}, 2: {'b': '2b'}}
To avoid the overwrite, you can do:
>>> d = {}
>>> for x, y, z in zip([1,1,2,2], ['a', 'b', 'a', 'b'], ['1a', '1b', '2a', '2b']):
... d.setdefault(x, {}).update({y:z})
...
>>> d
{1: {'a': '1a', 'b': '1b'}, 2: {'a': '2a', 'b': '2b'}}
The idea is to create a new dict for every new main key (setdefault(..., {})) and to update the dict associated with the main key (update({y:z})).
If you want a dict comprehension, this one will work:
>>> {x: {y:z for k, y, z in zip([1,1,2,2], ['a', 'b', 'a', 'b'], ['1a', '1b', '2a', '2b']) if k==x} for x in set([1,1,2,2])}
{1: {'a': '1a', 'b': '1b'}, 2: {'a': '2a', 'b': '2b'}}
But it's far less efficient than the for loop because you loop once over the first column to get the main keys, then once again over all the rows, for every main key.

Python3 toggle between two strings

Is there a more elegant way to toggle between two strings or integers in Python 3?
x={"A":"B", "B":"A"}[x]
The values can be non-boolean, like string or integer.
Let's suppose that we want to toggle between "A" and "B" and the variable name is x.
In other words: if x = "A" then the result should be x = "B" and if x = "B" then the result should be x = "A".
input:
x="B"
output:
x="A"
Using a dict is already pretty smart. Here is an alternative:
x = 'B' if x == 'A' else 'A'
You can write something like that:
def toggle(x):
x['A'], x['B'] = x['B'], x['A']
x = {'A': 'B', 'B': 'A'}
or that:
def toggle(x):
x.update(dict(zip(x.keys(), list(x.values())[::-1])))
x = {'A': 'B', 'B': 'A'}
print(x)
toggle(x)
print(x)
toggle(x)
print(x)
OUTPUT:
{'A': 'B', 'B': 'A'}
{'A': 'A', 'B': 'B'}
{'A': 'B', 'B': 'A'}

Resources