merging and calculating sum in dictionaries - python-3.x

let_col= {'t': ['black', 'golden', 'silver'], 'f': ['blue', 'green'], 's': ['grey', 'yellow'], 'k': ['red', 'purple']}
col_pix = {'blue':150,'red':200,'green':160,'grey':240,'purple':210,'black':140,'yellow':120,'golden':130,'silver':200}
I would like to merge these two dictionaries as :
let_col_pixels = {'t': ['black':140, 'golden':130, 'silver':200],'f':[] ....}
Then I have to add total pixels for each letter. can someone please help me , I tried many things but still unable to do it. Thanks

I hope I understand your question right, this script will merge the dictionaries and adds key total_sum to each letter:
let_col= {'t': ['black', 'golden', 'silver'], 'f': ['blue', 'green'], 's': ['grey', 'yellow'], 'k': ['red', 'purple']}
col_pix = {'blue':150,'red':200,'green':160,'grey':240,'purple':210,'black':140,'yellow':120,'golden':130,'silver':200}
out = {k: dict(**v, total_sum=sum(v.values())) for k, v in {k:{vv: col_pix[vv] for vv in v} for k, v in let_col.items()}.items()}
from pprint import pprint
pprint(out)
Prints:
{'f': {'blue': 150, 'green': 160, 'total_sum': 310},
'k': {'purple': 210, 'red': 200, 'total_sum': 410},
's': {'grey': 240, 'total_sum': 360, 'yellow': 120},
't': {'black': 140, 'golden': 130, 'silver': 200, 'total_sum': 470}}

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.

convert a df into a specific dictionary of dictionary in pandas

I have a df as shown below
Params Value
teachers 49
students 289
R 3.7
holidays 165
OS 18
Em_from 2020-02-29T20:00:00.000Z
Em_to 2020-03-20T20:00:00.000Z
Em_F 3
Em_C 2
sC_from 2020-03-31T20:00:00.000Z
sC_to 2020-05-29T20:00:00.000Z
sC_F 25
sC_C 31
From the above df I would like to convert that as a dictionary of dictionary as shown below.
dict:
{'teachers': 49,
'students': 289,
'R': 3.7,
'holidays': 165,
'OS':18,
'Em': {'from': '2020-02-29T20:00:00.000Z', 'to': '2020-03-20T20:00:00.000Z',
'F': 3, 'C': 2},
'sC': {'from': '2020-03-31T20:00:00.000Z', 'to': '2020-05-29T20:00:00.000Z',
'F': 25, 'C': 31}}
Use:
s = df['Params'].str.split('_')
m = s.str.len().eq(1)
d1 = df[m].set_index('Params')['Value'].to_dict()
d2 = df[~m].assign(Params=s.str[-1]).agg(tuple, axis=1)\
.groupby(s.str[0]).agg(lambda s: dict(s.tolist())).to_dict()
dct = {**d1, **d2}
Result:
{'Em': {'C': '2',
'F': '3',
'from': '2020-02-29T20:00:00.000Z',
'to': '2020-03-20T20:00:00.000Z'},
'OS': '18',
'R': '3.7',
'holidays': '165',
'sC': {'C': '31',
'F': '25',
'from': '2020-03-31T20:00:00.000Z',
'to': '2020-05-29T20:00:00.000Z'},
'students': '289',
'teachers': '49'}
Please always try to provide the data in a reproducible way, more people will be able to attempt the question
Dataset
Params = ['teachers','students','R','holidays','OS','Em_from','Em_to','Em_F','Em_C','sC_from','sC_to','sC_F','sC_C']
Value = ['49','289','3.7','165','18','2020-02-29T20:00:00.000Z','2020-03-20T20:00:00.000Z','3','2','2020-03-31T20:00:00.000Z','2020-05-29T20:00:00.000Z','25','31']
df = pd.DataFrame(zip(Params,Value),columns=["col1","col2"])
you can do something like
d = {}
for lst in df.values:
for k,v in zip(lst[0:],lst[1:]):
if any(name in k for name in ('Em_from', 'sC_from')):d[k.split('_')[0]] = {k.split('_')[1]:v}
elif any(name in k for name in ('Em_to', 'Em_F','Em_C','sC_to','sC_F','sC_C')):d[k.split('_')[0]][k.split('_')[1]] = v
else:d[k] = v
Output
{'teachers': '49',
'students': '289',
'R': '3.7',
'holidays': '165',
'OS': '18',
'Em': {'from': '2020-02-29T20:00:00.000Z',
'to': '2020-03-20T20:00:00.000Z',
'F': '3',
'C': '2'},
'sC': {'from': '2020-03-31T20:00:00.000Z',
'to': '2020-05-29T20:00:00.000Z',
'F': '25',
'C': '31'}}
panda's dataframes have a to_json method (see docs)
There are multiple examples there, but the general flow goes like this, let's say you have a dataframe called df:
import json
import pandas as pd
parsed = df.to_json()
df_json = json.loads(json_df)
Read the docs to see more examples and different parameters you may have to fiddle with.

Return multiple lines in a for loop

d = {'U': 4, '_': 2, 'C': 2, 'K': 1, 'D': 4, 'T': 6, 'Q': 1, 'V': 2, 'A': 9, 'F': 2, 'O': 8, 'J': 1, 'I': 9, 'N': 6, 'P': 2, 'S': 4, 'M': 2, 'W': 2, 'E': 12, 'Z': 1, 'G': 3, 'Y': 2, 'B': 2, 'L': 4, 'R': 6, 'X': 1, 'H': 2}
def __str__(self):
omgekeerd = {}
for sleutel, waarde in self.inhoud.items():
letters = omgekeerd.get(waarde, '')
letters += sleutel
omgekeerd[waarde] = letters
for aantal in sorted(omgekeerd):
return '{}: {}'.format(aantal, ''.join(sorted(omgekeerd[aantal])))
I need to return the value, followed by a ':' and then followed by every letter that has that value.
The problem is that when I use return, it only returns one value instead of every vale on a new line.
I can't use print() because that is not supported by the method str(self).
The return statement ends function execution and specifies a value to
be returned to the function caller.
I believe that your code is terminated too early because of wrong usage of return statement.
What you could do is to store what you would like to return in a seperate list/dictionary and then when everything is done, you can return the new dict/list that you've stored the results in.
If I understood you correctly; This is what might be looking for:
def someFunc():
d = {'U': 4, '_': 2, 'C': 2, 'K': 1, 'D': 4, 'T': 6, 'Q': 1, 'V': 2, 'A': 9,
'F': 2, 'O': 8, 'J': 1, 'I': 9, 'N': 6, 'P': 2, 'S': 4, 'M': 2, 'W': 2, 'E': 12,
'Z': 1, 'G': 3, 'Y': 2, 'B': 2, 'L': 4, 'R': 6, 'X': 1, 'H': 2}
result = {}
for key, value in d.iteritems():
result[value] = [k for k,v in d.iteritems() if v == value]
return result
# call function and iterate over given dictionary
for key, value in someFunc().iteritems():
print key, value
Result:
1 ['K', 'J', 'Q', 'X', 'Z']
2 ['C', 'B', 'F', 'H', 'M', 'P', 'W', 'V', 'Y', '_']
3 ['G']
4 ['D', 'L', 'S', 'U']
6 ['N', 'R', 'T']
8 ['O']
9 ['A', 'I']
12 ['E']

merging mulitple list of lists in python 3

let's say I have multiple lists of lists, I'll a include a shortened version of three of them in this example.
list1=[['name', '1A5ZA'], ['length', 83], ['A', 28], ['V', 31], ['I', 24]]
list2=[['name', '1AJ8A'], ['length', 49], ['A', 18], ['V', 11], ['I', 20]]
list3=[['name', '1AORA'], ['length', 96], ['A', 32], ['V', 49], ['I', 15]]
all of the lists are in the same format: they have the same number of nested lists, with the same labels.
I generate each of these lists with the following function
def GetResCount(sequence):
residues=[['A',0],['V',0],['I',0],['L',0],['M',0],['F',0],['Y',0],['W',0],
['S',0],['T',0],['N',0],['Q',0],['C',0],['U',0],['G',0],['P',0],['R',0],
['H',0],['K',0],['D',0],['E',0]]
name=sequence[0:5]
AAseq=sequence[27:]
for AA in AAseq:
for n in range(len(residues)):
if residues[n][0] == AA:
residues[n][1]=residues[n][1]+1
length=len(AAseq)
nameLsit=(['name', name])
lengthList=(['length', length])
residues.insert(0,lengthList)
residues.insert(0,nameLsit)
return residues
the script takes a sequence such as this
1A5ZA:A|PDBID|CHAIN|SQUENCEMKIGIVGLGRVGSSTAFAL
and will create a list similar to the ones mentioned above.
As each individual list is generated, I would like to append it to a final form, such that all of them combined together looks like this:
final=[['name', '1A5ZA', '1AJ8A', '1AORA'], ['length', 83, 49, 96], ['A', 28, 18, 32], ['V', 31, 11, 49], ['I', 24, 20, 15]]
maybe the final form of the data isn't in the right format. I am open to suggestion on how to format the final form better...
To summarize, what the script should do is to get a sequence of letters with the name of the sequence being at beginning, count the occurrence of each letter withing the sequence as well as the overall sequence length, and output the name length and the letter frequency to a list. Then it should combine the info from each sequence into a larger list(maybe dictionary?..)
at the very end all of this info will go into a spreadsheet that will look like this:
name length A V I
1A5ZA 83 28 31 24
1AJ8A 49 18 11 20
1AORA 96 32 49 15
I'm including this last bit because maybe I'm not starting starting in the right way to end up with what I want.
Anyway,
I hope you made it here and thanks for the help!
So if you are looking for a table then a dict might be a better approach. (Note: collections.Counter does the same as your counting), e.g.:
from collections import Counter
def GetResCount(sequence):
name, AAseq = sequence[0:5], sequence[27:]
residuals = {'name': name, 'length': len(AAseq), 'A': 0, 'V': 0, 'I': 0, 'L': 0,
'M': 0, 'F': 0, 'Y': 0, 'W': 0, 'S': 0, 'T': 0, 'N': 0, 'Q': 0, 'C': 0,
'U': 0, 'G': 0, 'P': 0, 'R': 0, 'H': 0, 'K': 0, 'D': 0, 'E': 0}
residuals.update(Counter(AAseq))
return residuals
In []:
GetResCount('1A5ZA:A|PDBID|CHAIN|SQUENCEMKIGIVGLGRVGSSTAFAL')
Out[]:
{'name': '1A5ZA', 'length': 19, 'A': 2, 'V': 2, 'I': 2, 'L': 2, 'M': 1, 'F': 1, 'Y': 0,
'W': 0, 'S': 2, 'T': 1, 'N': 0, 'Q': 0, 'C': 0, 'U': 0, 'G': 4, 'P': 0, 'R': 1,
'H': 0, 'K': 1, 'D': 0, 'E': 0}
Note: this may only be in the order you might be looking in Py3.6+ but we can fix that later as we create the table if necessary.
Then you can create a list of the dicts, e.g. (assuming you are reading these lines from a file):
with open(<file>) as file:
data = [GetResCount(line.strip()) for line in file]
Then you can load it directly into pandas, e.g.:
In []:
import pandas as pd
columns = ['name', 'length', 'A', 'V', 'I', ...] # columns = list(data[0].keys()) - Py3.6+
df = pd.DataFrame(data, columns=columns)
print(df)
Out[]:
name length A V I ...
0 1A5ZA 83 28 31 24 ...
1 1AJ8A 49 18 11 20 ...
2 1AORA 96 32 49 15 ...
...
You could also just dump it out to a file with cvs.DictWriter():
from csv import DictWriter
fieldnames = ['name', 'length', 'A', 'V', 'I', ...]
with open(<output>, 'w') as file:
writer = DictWrite(file, fieldnames)
writer.writerows(data)
Which would output something like:
name,length,A,V,I,...
1A5ZA,83,28,31,24,...
1AJ8A,49,18,11,20,...
1AORA,96,32,49,15 ...
...

Accessing values in nested dictionaries

I am trying to write a function that:
Counts the number of "sub-keys" of a key (e.g. 'e' is a sub-key of 'M')
Divides each sub-key's probability by the total number of sub-keys for that key
Modifies the numbers in place.
My function has to return None, however.
For example, if I had the dictionary:
defaultdict(dict, {'M': {'e': 1.0}, 'O': {'n': 2, 'x': 1.0}, 'I': {'_': 1.0, 's': 1}, 'P': {'t': 3}, 'L': {'ne': 1, 'n': 1.0}})
So for the example dictionary the converted dictionary output would be:
defaultdict(<class 'dict'>, {'M': {'e': 1.0}, 'O': {'n': 0.6666666666666666, 'x': 0.3333333333333333}, 'I': {'_': 0.5, 's': 0.5}, 'P': {'t': 1.0}, 'L': {'ne': 0.5, 'n': 0.5}})
Another example, if I had the dictionary:
defaultdict(dict, {('H', 't'): {'m': 2}, ('M', 'o'): {'ce': 1, 'p': 2}, ('K', '^'): {'d': 2}, ('F', 'x'): {'_': 1, 'g': 3}, ('J', 'o'): {'y': 1}, ('A', 'b'): {'k': 3}, ('X', '_'): {'r': 1}, ('N', 'e'): {'x': 1}})
The converted dictionary would be:
defaultdict(<class 'dict'>, {('M', 'o'): {'ce': 0.3333333333333333, 'p': 0.6666666666666666}, ('K', '^'): {'d': 1.0}, ('F', 'x'): {'g': 0.75, '_': 0.25}, ('J', 'o'): {'y': 1.0}, ('H', 't'): {'m': 1.0}, ('A', 'b'): {'k': 1.0}, ('X', '_'): {'r': 1.0}, ('N', 'e'): {'l': 1.0}})
How would I go about doing this? How do I access keys within a defaultdict of dictionaries. What I am currently thinking is:
for major_key in dictionary:
dictionary[major_key]...
...and that's where I get stuck.
Any help would be greatly appreciated!
Aside from being able to iterate over just the keys in dictionaries, in Python you can also iterate over key-value tuples , or just values. So we could do something like this:
for major_key, sub_dict in d.items():
total_key_count = 0
# Add up all sub key values to calculate probabilities
for sub_count in sub_dict.values():
total_key_count += sub_count
# Now update nested dictionary values accordingly
for minor_key, sub_count in sub_dict.items():
sub_dict[minor_key] = sub_count / total_key_count
That should help give you the results you want. Note in Python 2 you should call iteritems() instead of items(), since in Python 2 items() actually builds a list of tupes, rather than returning an iterator like iteritems() does. Same with values() and itervalues().

Resources