How to modify a Python JSON objects array - python

Let's assume the following :
sp_sample=[{"t":1434946093036,"v":54.0},{"t":1434946095013,"v":53.0},{"t":1434946096823,"v":52.0}
I wish I could get the following result :
sp_sample=[{"t":1434946093036,"v":5400.0},{"t":1434946095013,"v":5300.0},{"t":1434946096823,"v":5200.0}
In other words, I wish I could iterate through the array and multiple v by a 100 factor.
The following only performs the multiplication on the first item, ie yields 54000 :
for i, a in enumerate(sp_sample):
a[i]['v'] = a[i]['v'] * 100
The sp_sample is of type tuple. Using the following yields the whole array, which is not what I expect :
print sp_sample[0]
Also, tried printing sp_sample :
print sp_sample
Which returns the following (replaced the ....... for brevity) :
([{'t': 1434946093036, 'v': 54.0}, {'t': 1434946095013, 'v': 53.0}, {'t': 1434946096823, 'v': 52.0}, {'t': 1434946098612, 'v': 52.0}, {'t': 1434946100400, 'v': 51.0}, {'t': 1434946102372, 'v': 49.0},........, {'t': 1434947987823, 'v': 15.0}, {'t': 1434947989851, 'v': 12.0}, {'t': 1434947991899, 'v': 10.0}, {'t': 1434947993744, 'v': 5.0}, {'t': 1434947995599, 'v': 0.0}, {'t': 1434947997455, 'v': 0.0}, {'t': 1434947999494, 'v': 0.0}, {'t': 1434948001542, 'v': 0.0}, {'t': 1434948003417, 'v': 0.0}, {'t': 1434948005264, 'v': 0.0}, {'t': 1434948007120, 'v': 0.0}],)
print type(sp_sample) returns :

Simply iterate over the list and update the dictionaries as you go:
sp_sample = [{"t":1434946093036,"v":54.0},{"t":1434946095013,"v":53.0},{"t":1434946096823,"v":52.0}]
for d in sp_sample:
d['v'] *= 100
>>> print(sp_sample)
[{'t': 1434946093036, 'v': 5400.0}, {'t': 1434946095013, 'v': 5300.0}, {'t': 1434946096823, 'v': 5200.0}]
This will bind in turn each dictionary in list (tuple?) sp_sample to d, which you then update in place. You do not need to use enumerate().
Note that you really need to multiply by 100, not 10000, to achieve the output that you have shown.
Update
sp_sample is actually a tuple with a list of dictionaries as its only item. So you need to access the list in the tuple like this:
sp_sample = ([{"t":1434946093036,"v":54.0},{"t":1434946095013,"v":53.0},{"t":1434946096823,"v":52.0}],)
for d in sp_sample[0]: # N.B. access first item of tuple
d['v'] *= 100
>>> print(sp_sample)
[{'t': 1434946093036, 'v': 5400.0}, {'t': 1434946095013, 'v': 5300.0}, {'t': 1434946096823, 'v': 5200.0}]
Or, since the tuple contains only a single item you could just get rid of the tuple by:
sp_sample = sp_sample[0]
for d in sp_sample:
d['v'] *= 100

Related

How to print specific values from dict_items?

I have a dict_items called results which contains the following:
dict_items([('rouge-1', {'r': 1.0, 'p': 1.0, 'f': 0.999999995}), ('rouge-2', {'r': 1.0, 'p': 1.0, 'f': 0.999999995}), ('rouge-l', {'r': 1.0, 'p': 1.0, 'f': 0.999999995})])
What I want to do is to extract the values of f from all items rouge-1, rouge-2 and rouge-l
How can I do it?
Try:
results = get_scores() # <-- the results contains your dict_item(...)
for k, v in results:
print(k, v["f"])
for name in ('rouge-1','rouge-2','rouge-l'):
print( dict_items[name]['f'] )
If you want ALL of the items, there's an easier way;
for k,v in dict_items.items():
print(k, v['f'])

How do I access something within a dictionary, thats within a list, thats within a dictionary?

How would I access the object 'c' in a print statement?
{'symbol': 'BTCUSD', 'totalResults': 1, 'results': [{'o': 41002.26, 'h': 43361, 'l': 40875.51, 'c': 42364.13, 'v': 59454.94294, 't': 1647993599999}]}
Overall code(API KEY REMOVED BUT ISNT THE ISSUE):
command = ""
while(command != "q"):
command = input("Choose [c] for current price, [p] for previous days price, and [q] to quit.")
if(command == "c"):
coin = input("Enter currency pair: ")
crypto_data = (requests.get(f'https://api.finage.co.uk/last/crypto/{coin}?apikey=API_KEY')).json()
print(f"The current price of {coin} is {crypto_data['price']}")
if(command == "p"):
coin = input("Enter currency pair: ")
crypto_data = (requests.get(f'https://api.finage.co.uk/agg/crypto/prev-close/{coin}?apikey=API_KEY')).json()
*print(f"The previous price of {coin} is {crypto_data['results']['c']}")*
being where I get the issue
I get back a variety of codes, mostly I cant call a string and it must be a slice or integer
I have tried a range statement as well but it also brings back an error
TIA!
The same way you would do it if they were in a dictionary first, then an array, and then a dictionary again:
crypto_data = {'symbol': 'BTCUSD', 'totalResults': 1, 'results': [{'o': 41002.26, 'h': 43361, 'l': 40875.51, 'c': 42364.13, 'v': 59454.94294, 't': 1647993599999}]}
print(crypto_data["results"][0]["c"])
This is because:
# crypto_data is a dictionary, so you can access items by their key, i.e.
crypto_data["results"]
# which returns an array: [{'o': 41002.26, 'h': 43361, 'l': 40875.51, 'c': 42364.13, 'v': 59454.94294, 't': 1647993599999}]
# so then access items in the array by their index, i.e.
crypto_data["results"][0]
# which returns a dictionary: {'o': 41002.26, 'h': 43361, 'l': 40875.51, 'c': 42364.13, 'v': 59454.94294, 't': 1647993599999}
# so then access items in the dictionary by their key again, i.e.
crypto_data["results"][0]["c"]
# which returns an integer: 42364.13
if
myDict = {'symbol': 'BTCUSD', 'totalResults': 1, 'results': [{'o': 41002.26, 'h': 43361, 'l': 40875.51, 'c': 42364.13, 'v': 59454.94294, 't': 1647993599999}]}
then myDict["results"][0]["c"] would return 42364.1
It's because despite you know that the dictionary is within a list, you're trying to access the dictionary as if it wasn't within a list.
This is really important: this API can return more than one dictionary in the results list - see the totalResults key.
The best way to get the results is to do a for ... range loop:
for idx in range(crypto_data['totalResults']): print(crypto_data['results'][idx])

Get slice of Python list based on indices: list of list of dicts

I have a structure as below:
[[{'w': [0.5372377247650572, 1.9111341091016385, -3.2165806256024116, -1.7154987465370053, 1.0917999534858416], 'o': 0.0004326739879156587, 'd': 3.586499431857422e-05}],[{'w': [7.298542669399767, -3.9021024252822105], 'o': 0.019860841402923542, 'd': 0.00105997759946847}, {'w': [-2.8024625186056764, -0.34819658506990847], 'o': 0.4135257109795849, 'd': -0.0016469874583619935}, {'w': [-6.018257518762189, 0.3317488378886934], 'o': 0.5815513019444986, 'd': -1.1787471334339458e-05}]]
It is a list of lists of dicts, and these dicts contain keys 'w', 'o', 'd'. I want to create a slice of this structure such that I'm left with only the 'd' values:
3.586499431857422e-05, 0.00105997759946847, -0.0016469874583619935, -1.1787471334339458e-05
How can this be done?
structure = [[{'w': [0.5372377247650572, 1.9111341091016385, -3.2165806256024116, -1.7154987465370053, 1.0917999534858416], 'o': 0.0004326739879156587, 'd': 3.586499431857422e-05}],[{'w': [7.298542669399767, -3.9021024252822105], 'o': 0.019860841402923542, 'd': 0.00105997759946847}, {'w': [-2.8024625186056764, -0.34819658506990847], 'o': 0.4135257109795849, 'd': -0.0016469874583619935}, {'w': [-6.018257518762189, 0.3317488378886934], 'o': 0.5815513019444986, 'd': -1.1787471334339458e-05}]]
d_values = [ x['d'] for row in structure for x in row ]
Without list comprehension:
res=[]
for list_dicts in original_matrix:
for current_dict in list_dicts:
res.append(current_dict['d'])
print(res)

a string to a dictionary of dictionary

Hi I want to create a dictionary of dictionary but I can't for a text and in an iterative way…. and I am obligated to create a lot of variable and I want that the creation of the dictionary to be automatical without the creation of variables. Can you help me to improve it ?
I tried to create two functions and create this dictionary with one word…
def create_last_dictionary(word, n):
dico={}
dico[word[len(word) - n]] = {}
return dico
def create_dictionary(dic_to_add, word, n):
dic = {}
dic[word[len(word) - n]]=dic_to_add
return dic
word = "mommy"
one = create_last_dictionary(word, 1)
two = create_dictionary(one, word, 2)
three = create_dictionary(two, word, 3)
four = create_dictionary(three, word, 4)
five = create_dictionary(four, word, 5)
six = create_dictionary(five, word, 6)
seven = create_dictionary(six, word, 7)
result :
{'m': {'o': {'r': {'n': {'i': {'n': {'g': {}}}}}}}}
I want it for a list of words like :
if the list is : ["good", "Morning", "mommy"]
I want the dictionary to be :
{{'g': {'o': {'o': {'d': {}}}}}, 'm': {'o': {'m': {'m': {'y': {}}}}, {'r': {'n': {'i': {'n': {'g': {}}}}}}}}
the representation of the dictionary :
{
{'g': {'o': {'o': {'d': {}}}}},
{'m': {'o': {{'m': {'m': {'y': {}}}},
{'r': {'n': {'i': {'n': {'g': {}}}}}}}}}
}
You need to create a function which inserts a new word in an existing (maybe empty) tree. To achieve this I propose a recursive function:
def insert(tree, path):
if path:
insert(tree.setdefault(path[0], {}), path[1:])
Now you can use it:
tree = {}
insert(tree, 'good')
insert(tree, 'morning')
insert(tree, 'mommy')
print(tree)
prints
{'m': {'o': {'m': {'m': {'y': {}}},
'r': {'n': {'i': {'n': {'g': {}}}}}}},
'g': {'o': {'o': {'d': {}}}}}
EDIT:
In case you don't like using .setdefault() because it seems a hard-to-read shortcut, consider this:
def insert(tree, path):
if path:
if path[0] not in tree:
tree[path[0]] = {}
insert(tree[path[0]], path[1:])
Instead of chaining function calls, you could create a recursive function; your are almost there as you created two cases already. I found a course about Python recursive functions here: https://www.python-course.eu/python3_recursive_functions.php

Merge two lists into a dictionary and sum over the elements of the second list

If I have two lists (with the same length):
ls1 = ['a','b','c','a','d','c']
ls2 = [1,2,3,5,1,2]
I would like to get the following dictionary (sum over the values if it is the same key):
d = {'a':6,'b':2,'c':5,'d':1}
I did the following:
ls1 = np.array(ls1)
ls2 = np.array(ls2)
uniqe_vals = list(set(ls1))
d = {}
for u in uniqe_vals:
ind = np.where(ls1 == u)[0]
d[u] = sum(ls2[ind])
It works fine for small data, but it is taking too long for the whole data (I have a list of size ~5 million).
Do you have any suggestions for a more efficient way to do it ?
Also with a defaultdict, but different and simpler:
from collections import defaultdict
d = defaultdict(int)
for n, v in zip(ls1, ls2):
d[n] += v
Or, as suggested:
from collections import defaultdict
from itertools import izip
d = defaultdict(int)
for n, v in izip(ls1, ls2):
d[n] += v
You could try:
import numpy as np
uni, i = np.unique(ls1, return_inverse=1)
vals = np.bincount(i, ls2)
dict(zip(uni, vals))
Since you asked how to make it more efficient, I compared the time your original solution took with the version suggested in my comment (equivalent with Juergen's second solution) with 5 million random characters from a-z as keys and 5 million random values from 0-20, using my shell's time function:
~/test $ time python defdict.py
defaultdict(<type 'int'>, {'a': 381956, 'c': 383815, 'b': 378277, 'e': 384629, 'd': 383557, 'g': 381139, 'f': 386268, 'i': 383902, 'h': 385809, 'k': 385138, 'j': 384690, 'm': 388552, 'l': 384393, 'o': 384533, 'n': 385011, 'q': 385685, 'p': 386188, 's': 387132, 'r': 383886, 'u': 386176, 't': 387144, 'w': 386371, 'v': 388263, 'y': 381337, 'x': 385281, 'z': 384048})
python defdict.py 13,24s user 0,35s system 96% cpu 14,045 total
~/test $ time python original.py
{'a': 386316, 'c': 383596, 'b': 383424, 'e': 385598, 'd': 383324, 'g': 382233, 'f': 385435, 'i': 386761, 'h': 384047, 'k': 386640, 'j': 386313, 'm': 381032, 'l': 383035, 'o': 389142, 'n': 385000, 'q': 386088, 'p': 387435, 's': 385429, 'r': 384260, 'u': 385442, 't': 384793, 'w': 385052, 'v': 380830, 'y': 386500, 'x': 386871, 'z': 379870}
python original.py 14,68s user 0,38s system 96% cpu 15,529 total
So there seems to be a difference, although not a big one. To make it fairer, numpy was also imported in defdict.py.

Categories