I want to implement a use case through hashmap in python. I will be having a json object of type dict.
x={
"name": "Jim",
"age": 30,
"married": True,
"phonenumber": "123456"
"pets": None,
"cars": [
{"model": "toyota", "mpg": 23.5},
{"model": "kia", "mpg": 21.1}
]
}
if (x["married"] == True):
h.put(x[phonenumber]) // i want to make phonenumber as key and the entire dict x as value. by using something like Map<String, dict> h = new HashMap<>();
when i do h.get(phonenumber), i want the entire dict x as an output.
How can i implement this usecase in python.
A dict is python's version of a hash map. To do what you want, try the following:
m = {}
if x["married"]:
m[x["phonenumber"]] = x
As has already been said, the dict() is Python's implementation of hastmaps / hash tables. I've assumed that you are going to have many records, all of which will be stored in a dict(), and that you are adding records according to your example. I have not error-checked for the existence of a phone number in the record; since you're using the phone number as the key then you should already have ensured that there is an actual phone number in the information which you are adding.
#just one record
x={
"name": "Jim",
"age": 30,
"married": True,
"phonenumber": "123456", #you left out a comma here
"pets": None,
"cars": [
{"model": "toyota", "mpg": 23.5},
{"model": "kia", "mpg": 21.1}
]
}
my_dict = dict() #this would hold ALL of your records
def add_to_mydict(my_dict:dict, new_record:dict):
if new_record["married"]:
phone = new_record.pop("phonenumber")
y = {phone: new_record}
my_dict.update(y)
add_to_mydict(my_dict, x)
print(my_dict)
my_dict would be the master dictionary in which you will store your data. SQLite makes a much better database than in-memory dicts.
Related
I am iterating over a list of dictionaries in a list formatted as follows (each dictionary relates to one item of clothing, I have only listed the first:
new_products = [{'{"uniq_id": "1234", "sku": "abcdefgh", "name": "Levis skinny jeans", '
'"list_price": "75.00", "sale_price": "55.00", "category": "womens"}'}]
def find_product(dictionary, uniqid):
if 'uniq_id' in dictionary:
if ['uniq_id'] == uniqid:
return(keys, values in dictionary)
print(find_product(new_products, '1234'))
This is returning
None
The reason for the if statement in there is that not every product has a value for uniq_id so I was getting a key error on an earlier version of my code.
Your dictionary definition is quite unclear.
Assuming that you have given a list of dictionaries of size 1, it should be something like this:
new_products = [{"uniq_id": "1234", "sku": "abcdefgh", "name": "Levis skinny jeans", "list_price": "75.00", "sale_price": "55.00", "category": "womens"}]
def find_product(list_of_dicts, uniqid):
for dictionary in list_of_dicts:
if 'uniq_id' in dictionary:
if dictionary['uniq_id'] == uniqid:
return dictionary
print(find_product(new_products, '1234'))
You are using something like this:
new_products = [{'{ "some" : "stuff" }'}]
This is a list (the outer []) containing a set (the {})
{'{ "some" : "stuff" }'}
Note {1} is a set containing the number 1. Though it uses the curly braces it isn't a dictionary.
Your set contains a string:
'{ "some" : "stuff" }'
If I ask if 'some' is in this, I get True back, but if I ask for this string's keys there are no keys.
Make your new_products a list containing a dictionary (not a set), and don't put the payload in a string:
new_products = [{"uniq_id": "1234",
"sku": "abcdefgh",
"name": "Levis skinny jeans",
"list_price": "75.00",
"sale_price": "55.00",
"category": "womens"}]
Then loop over the dictionaries in the list in your function:
def find_product(dictionary_list, uniqid):
for d in dictionary_list:
if 'uniq_id' in d:
if d['uniq_id'] == uniqid:
return d.keys(), d.values()
return "not found" # or something better
>>> find_product(new_products, '1234')
(dict_keys(['uniq_id', 'sku', 'name', 'list_price', 'sale_price', 'category']), dict_values(['1234', 'abcdefgh', 'Levis skinny jeans', '75.00', '55.00', 'womens']))
>>> find_product(new_products, '12345')
'not found'
I have a JSON like below:
[
[
{
"subject": "Subject_1",
"qapali_correct_count": "12"
},
{
"subject": "Subject_2",
"qapali_correct_count": "9"
}
],
[
{
"subject": "Subject_1",
"qapali_correct_count": "14"
},
{
"subject": "Subject_2",
"qapali_correct_count": "15"
}
],
[
{
"subject": "Subject_1",
"qapali_correct_count": "11"
},
{
"subject": "Subject_2",
"qapali_correct_count": "12"
}
]
]
I have to output every subject's average: for example: subject_1 = 12.33, subject_2=12
I tried this code it works but I just wonder is there any option to speed up this code, Are there any other efficient ways to achieve it.
results = Result.objects.filter(exam=obj_exam, grade=obj_grade)
student_count = results.count()
final_data = {}
for result in results:
st_naswer_js = json.loads(result.student_answer_data_finish)
for rslt in st_naswer_js:
previus_data = final_data.get(rslt['subject'],0)
previus_data = previus_data+int(rslt['qapali_correct_count'])
final_data.update({rslt['subject']:previus_data})
for dudu, data in final_data.items():
tmp_data = data/student_count
final_data[dudu]=tmp_data
print(final_data)
Please note that it is a Django project.
The code in your question has several non-relevant bits. I'll stick to this part:
I have to output every subject's average: for example: subject_1 = 12.33, subject_2=12
I'll assume the list of results above is in a list called results. If it's json-loaded per student, handling that is probably already in your existing code. Primary focus below is on subject_score.
Store the score of each subject in a dictionary, whose values are lists of scores. I'm using a defaultdict here, with list as the default factory so when a dictionary value which doesn't exist is accessed, it gets initialised to an empty list (rather than throwing an KeyError which would happen with a standard dictionary.
import collections
subject_score = collections.defaultdict(list)
for result in results:
for stud_score in result:
# add each score to the list of scores for that subject
# use int or float above as needed
subject_score[stud_score['subject']].append(int(stud_score['qapali_correct_count']))
# `subject_score` is now:
# defaultdict(list, {'Subject_1': [12, 14, 11], 'Subject_2': [9, 15, 12]})
averages = {sub: sum(scores)/len(scores) for sub, scores in subject_score.items()}
averages is:
{'Subject_1': 12.333333333333334, 'Subject_2': 12.0}
Or you can print or save to file, db, etc. as needed.
bus_stops = jsoncalls.get_bus_stop()
print(len(bus_stops))
stop_map = {stop['Description']: stop for stop in bus_stops}
print('extracted dic: '+str(len(stop_map)))
here is what my code looks like. basically i create a dictionary out of another method i have from an api call. then i did what i think was to create another dictionary populated with only the values "description" from that dictionary.
the first print is the length of the first dictionary. the second print is the length of the second.
5024
extracted dic: 4457
the second dictionary is 600 items short! i am perplexed as to what could have caused this. can anyone advice me?
You're grouping the items by description by using it as a key. A key can only exist once. If two items have the same description, they'll occupy the same key, of which only the last one will survive.
Since dict keys are unique, I would bet you have repeated descriptions in your source dict. For example, suppose you have the following dataset:
bus_stops = [
{"Id": 1, "Description": "spam"},
{"Id": 2, "Description": "cheese"},
{"Id": 3, "Description": "spam"},
]
Note how only the last "spam" will be present in the result:
>>> stop_map = {stop['Description']: stop for stop in bus_stops}
{
'cheese': {'Description': 'cheese', 'Id': 2},
'spam': {'Description': 'spam', 'Id': 3}},
}
If this is the case and you want to group stops by description, you can use a dict with description as key and a list of stops as value - the setdefault method is handy for this kind of data transformation:
stop_map = {}
for stop in bus_stops:
stop_map.setdefault(stop["Description"], []).append(stop)
Result:
{
"cheese": [
{
"Id": 2,
"Description": "cheese"
},
],
"spam": [
{
"Id": 1,
"Description": "spam"
},
{
"Id": 3,
"Description": "spam"
},
],
}
This question already has answers here:
Items in JSON object are out of order using "json.dumps"?
(8 answers)
Closed 4 years ago.
I need to show an output like below as a result of a webservice call
{
"predictions": [
{
"id": 18009,
"cuisine": "italian",
"probability": 0.17846838753494407
},
{
"id": 28583,
"cuisine": "italian",
"probability": 0.1918703125538735
}
]
}
I have the below code to create the object:
json_data = []
for i in range (0, len(predicted_labels)):
data = {}
data['id'] = int(test['id'][i])
data['cuisine'] = categoricalTransformer[predicted_labels[i]]
item = predicted_probability[i]
data['probability'] = item[predicted_labels[i]]
json_data.append(data)
json_return = {"predictions":json_data}
return jsonify(json_return)
which reorders the key alphabetically as shown below.
{
"predictions": [
{
"cuisine": "italian",
"id": 18009,
"probability": 0.17846838753494407
},
{
"cuisine": "italian",
"id": 28583,
"probability": 0.1918703125538735
}
]
}
What should I do?
Rebuild your new dictionary with a collections.defaultdict(), and append ordered dictionaries with a collections.OrderedDict():
from collections import OrderedDict
from collections import defaultdict
from json import dumps
data = {
"predictions": [
{"id": 18009, "cuisine": "italian", "probability": 0.17846838753494407},
{"id": 28583, "cuisine": "italian", "probability": 0.1918703125538735},
]
}
key_order = ["id", "cuisine", "probability"]
result = defaultdict(list)
for dic in data["predictions"]:
ordered = OrderedDict((key, dic.get(key)) for key in key_order)
result["predictions"].append(ordered)
print(dumps(result))
# {"predictions": [{"id": 18009, "cuisine": "italian", "probability": 0.17846838753494407}, {"id": 28583, "cuisine": "italian", "probability": 0.1918703125538735}]}
json.dumps() here serializes the dictionary into a JSON formatted string.
Note: If you are using Python3.6+, you can use normal dictionaries instead of OrderedDict(), since insertion order of keys is remembered. However, in 3.6 it is an implementation feature, whereas in 3.7 it is a language feature. You read more about this at Are dictionaries ordered in Python 3.6+?.
You can probably rely on this feature for applications that have a minimum requirement of Python3.6. Furthermore, its probably safer to user OrderedDict() anyways, so your code can be backwards compatible for all python versions.
You can look into Ordered Dictionary. It remembers the insertion order, and you would be able to organise your json via this collection this way.
Example:
datadict = {'a':'a', 'c':'c', 'b':'b'}
import collections
print (collections.OrderedDict(datadict))
#OrderedDict([('a':'a'), ('c':'c'), ('b':'b')])
x = collections.OrderedDict(datadict)
print (dict(x))
#{'a':'a', 'c':'c', 'b':'b'}
print (x == datadict)
#True
print (collections.OrderedDict(sorted(datadict.items(), key=lambda t:t[0])))
#OrderedDict([('a':'a'), ('b':'b'), ('c':'c')])
z = collections.OrderedDict(sorted(datadict.items(), key=lambda t:t[0]))
print (dict(z))
#{'a':'a', 'b':'b', 'c':'c'}
print (z == datadict)
#True
Using this, you can convert your json_return dict object into an OrderedDict with your desired insertion order and then return that OrderedDict object or convert it back into a dict and return that dict
I'm currently trying to search for entries inside my Redis that match a specific value through an HTTP API the same way you'd do with a regular DB (eg: http://localhost:8000/api?name=John&age=20) with the redis python library (https://pypi.org/project/redis/).
The code I have thus far returns the whole hash, converts each entry into a JSON and adds it to a list
import json
import redis
import os
r = redis.StrictRedis(host=os.environ['redis_url'], port=os.environ['redis_port'], password=os.environ['redis_pass'], ssl=True)
result = r.hgetall('Directory')
dic_list = []
for key in result.keys():
dic_list.append(json.loads(result[key].decode('utf-8')))
return dic_list
I know that I can get the value of a specific key with
r.hget('Directory', 'key_I_want')
However inside each key there is a whole JSON full with information, so for example this would be a key, value example inside of the Directory hash
"1": {
"name": "James",
"age": "22",
"favorite_color":"Green"
},
"2":{
"name":"John",
"age": "20",
"favorite_color": "red"
},
"3":{
"name":"Jim",
"age": "30",
"favorite_color": "yellow"
}
So I know
r.hget('Directory', '1')
would return
{
"name": "James",
"age": "22",
"favorite_color":"Green"
}
But what I really want is to look for every JSON that has specific values, not just to get the values of each key inside the hash, is there any way to actually do that?
Based on your question, you are, maybe, looking for a value within results[key]. Assumin that value is equal to val, try:
for key in result.keys():
if val in result[key].values():
dic_list.append(json.loads(result[key].decode('utf-8')))
for example, if
val = "James"
Yoy will get all results with James in the value.
You can mix it up a little, change it the way you want it.