I am loading data from json files using load method and then putting the items in a new python object.
obj_1 = json.load(file)
obj_2 = obj_1.items()
When I run the code in python2, type(obj_2) is list. But when I run in python 3, type(obj_2) is 'dict_items'. Because of that when I run following code:
sorted_items = sorted (obj_2[1][1]['string'])
I'm getting this error in python 3:
TypeError: 'dict_items' object does not support indexing
In python 2 it runs fine. How can I solve this issue in python 3? I have found some related questions about this but the answers doesn't solve my particular case. I have tried to use list(obj_2) but it causes key error.
json file format is something like this:
{
"item_1": {
"item_2": {
"string": 111111,
"string": 222222,
"string": 333333,
................
................
},
},
}
I want to sort the "item_2" contents according to the keys in ascending order.
simply
d = { .... }
l = list(d.items())
making a for loop here is the best option i can think of.
object_list = []
for key, value in obj_2:
entry = [key, value]
object_list.append(entry)
that would store the key and value in a list that is inside another list.
EDIT
Found a better way to do it!
my_dict = {"hello": "there", "how": "are you?"}
my_list = [[x, y] for x, y in my_dict.items()]
# out => [['hello', 'there'], ['how', 'are you?']]
Convert dict items (keys and values) to a list with one line of code. Example:
example_dictionary = {"a": 1, "b": 2, "c": 3}
dict_items_to_list = [*foo.keys(), *foo.values()]
print(dict_items_to_list)
>>> ['a', 'b', 'c', 1, 2, 3]
Related
I'm using the Python library glom to extract data from a dictionary that contains lists.
This question is about unterstanding how glom works with user defined functions and how I can move data from lists into dictionaries within glom.
As an example, I'm trying to convert the data into a dictionary directly.
# in the real world, this data has way many more fields
data = {'vessels': [{'aisStatic': {'mmsi': 1, 'name': 'name1'}},
{'aisStatic': {'mmsi': 2, 'name': 'name2'}}],
'timestamp': None}
# this is the glob spec to extract the data
spec = ('vessels',[({'mmsi':'aisStatic.mmsi','name':'aisStatic.name'})])
# an example to generate a new key based on data & position
def keyfunc(i, v):
return f"v{i}-{v['mmsi']}"
result = glom(data, spec)
wanted_result = {keyfunc(i,v): v for i, v in enumerate(result)}
The wanted result looks like this
{'v0-1': {'mmsi': 1, 'name': 'name1'}, 'v1-2': {'mmsi': 2, 'name': 'name2'}}
For the example, I'm using a comprehension outside of glom to get the wanted result, since glom returns a list.
I am looking at a way to get the same results directly via a glom spec.
A working solution is to use Invoke on the enumerate function.
from glom import merge, Invoke
data = {
"vessels": [
{"aisStatic": {"mmsi": 1, "name": "name1"}},
{"aisStatic": {"mmsi": 2, "name": "name2"}},
],
"timestamp": None,
}
spec = (
"vessels",
[{"mmsi": "aisStatic.mmsi", "name": "aisStatic.name"}],
Invoke(enumerate).specs(T),
[lambda x: {f"v{x[0]}-{x[1].get('mmsi')}": x[1]}],
merge,
)
print(glom(data, spec))
which returns the requested result
{'v0-1': {'mmsi': 1, 'name': 'name1'}, 'v1-2': {'mmsi': 2, 'name': 'name2'}}
I have a dictionary in Python as follows:
result = {"name":"testipgroup",
"ips": ["10.1.1.7","10.1.1.8"],
"team_name": "avengers"}
The output I need is in this format :
result = {"name":"testipgroup",
"ips": [{"name":"IP_10.1.1.7", "value":"10.1.1.7"}],
"team_name": "avengers"}
My implementation involves popping the 'ips' list from the result dict, iterating over the list, doing transformations and then appending the new list of dicts to the result dict as follows:
a = result.pop("ips")
result["ips"] = []
for item in a:
ip_dict = {}
ip_dict.update({"name": "IP_" + str(item), "value": str(item)})
result["ips"].append(ip_dict)
Is there a cleaner way of doing this without popping and creating a new array and doing this directly on the result dict
You can use list comprehension:
result['ips'] = [{'name': 'IP_' + i, 'value': i} for i in result['ips']]
result would become:
{'name': 'testipgroup', 'ips': [{'name': 'IP_10.1.1.7', 'value': '10.1.1.7'}, {'name': 'IP_10.1.1.8', 'value': '10.1.1.8'}], 'team_name': 'avengers'}
It seems like you just want to map over the list and wrap it in a dictionary, with a few tweaks to it? If so, why don't you try using list comprehension?
result['ips'] = [{ 'name':'IP_' + ip, 'value': ip } for ip in result['ips']]
I am currently using Python 3.5.2.
I have a dataset comprising of a list of dictionaries such as below (actual dataset has over 100 such entries):
MyList = [{"Class":1, "ID":123, "Name":"Sam", "Marks":90},
{"Class":1, "ID":124, "Name":"Jack", "Marks":91},
{"Class":1, "ID":125, "Name":"Dan", "Marks":92},
{"Class":2, "ID":234, "Name":"Sammy", "Marks":82},
{"Class":2, "ID":235, "Name":"Jacky", "Marks":85}]
I wanted to get the summary comprising as below:
ClassSummary = [{"Class":1, "TotalStudents": 3, "AvgMarks":91},
{"Class":2, "TotalStudents": 2, "AvgMarks":83.5}]
where TotalStudents refer to count of "Name" in each Class
and AvgMarks refer to Average of "Marks" in each Class.
I am fairly new to list of dictionaries, so any leads on how to approach this would be of great help.
[Edit] Here is what I have tried so far:
class_set = set()
for dict in MyList:
class_set.add(dict["Class"])
This gives me list of different classes available in my List. But I am not sure how to proceed further for subsequent arithmetic operations.
Thanks
It's a bit messy, but here is my solution that works fine:
ClassSummary = []
cls = 0
for d in MyList:
if d["Class"] != cls:
ClassSummary.append({"Class": d["Class"], "TotalStudents": 1, "AvgMarks": d["Marks"]})
cls = d["Class"]
else:
ClassSummary[d["Class"]-1]["TotalStudents"] += 1
ClassSummary[d["Class"]-1]["AvgMarks"] += d["Marks"]
for s in ClassSummary:
s["AvgMarks"] /= s["TotalStudents"]
which gives ClassSummary as:
[{'TotalStudents': 3, 'AvgMarks': 91.0, 'Class': 1}, {'TotalStudents': 2, 'AvgMarks': 83.5, 'Class': 2}]
as you asked for!
I have the following:
list_of_values = []
x = { 'key1': 1, 'key2': 2, 'key3': 3 }
How can I iterate through the dictionary and append one of those values into that list? What if I only want to append the value of 'key2'.
If you only want to append a specific set of values you don't need to iterate through the dictionary can simply add it to the list
list_of_values.append(x["key2"])
However, if you insist on iterating through the dictionary you can iterate through the key value pairs:
for key, value in x.items():
if key == "key2":
list_of_values.append(value)
If you really want to iterate over the dictionary I would suggest using list comprehensions and thereby creating a new list and inserting 'key2' :
list_of_values = [x[key] for key in x if key == 'key2']
because that can be easily extended to search for multiple keywords:
keys_to_add = ['key2'] # Add the other keys to that list.
list_of_values = [x[key] for key in x if key in keys_to_add]
That has the simple advantage that you create your result in one step and don't need to append multiple times. After you are finished iterating over the dictionary you can append the list, just to make it interesting, you can do it without append by just adding the new list to the older one:
list_of_values += [x[key] for key in x if key in keys_to_add]
Notice how I add them in-place with += which is exactly equivalent to calling list_of_values.append(...).
list_of_values = []
x = { 'key1': 1, 'key2': 2, 'key3': 3 }
list_of_values.append(x['key2'])
I'm still trying to figure it out how nested dictionaries in python really works.
I know that when you're using [] it's a list, () it's a tuple and {} a dict.
But when you want to make a nested dictionaries like this structure (that's what a i want) :
{KeyA :
{ValueA :
[KeyB : ValueB],
[Keyc : ValueC],
[KeyD : ValueD]},
{ValueA for each ValueD]}}
For now I have a dict like:
{KeyA : {KeyB : [ValueB],
KeyC : [ValueC],
KeyD : [ValueD]}}
Here's my code:
json_file = importation()
dict_guy = {}
for key, value in json_file['clients'].items():
n_customerID = normalization(value['shortname'])
if n_customerID not in dict_guy:
dict_guy[n_customerID] = {
'clientsName':[],
'company':[],
'contacts':[], }
dict_guy[n_customerID]['clientsName'].append(n_customerID)
dict_guy[n_customerID]['company'].append(normalization(value['name']))
dict_guy[n_customerID]['contacts'].extend([norma_email(item) for item in v\
alue['contacts']])
Can someone please, give me more informations or really explain to me how a nested dict works?
So, I hope I get it right from our conversation in the comments :)
json_file = importation()
dict_guy = {}
for key, value in json_file['clients'].items():
n_customerID = normalization(value['shortname'])
if n_customerID not in dict_guy:
dict_guy[n_customerID] = {
'clientsName':[],
'company':[],
'contacts':{}, } # Assign empty dict, not list
dict_guy[n_customerID]['clientsName'].append(n_customerID)
dict_guy[n_customerID]['company'].append(normalization(value['name']))
for item in value['contacts']:
normalized_email = norma_email(item)
# Use the contacts dictionary like every other dictionary
dict_guy[n_customerID]['contacts'][normalized_email] = n_customerID
There is no problem to simply assign a dictionary to a key inside another dictionary. That's what I do in this code sample. You can create dictionaries nested as deep as you wish.
How that this helped you. If not, we'll work on it further :)
EDIT:
About list/dict comprehensions. You are almost right that:
I know that when you're using [] it's a list, () it's a tuple and {} a dict.
The {} brackets are a little tricky in Python 3. They can be used to create a dictionary as well as a set!
a = {} # a becomes an empty dictionary
a = set() # a becomes an empty set
a = {1,2,3} # a becomes a set with 3 values
a = {1: 1, 2: 4, 3: 9} # a becomes a dictionary with 3 keys
a = {x for x in range(10)} # a becomes a set with 10 elements
a = {x: x*x for x in range(10)} # a becomes a dictionary with 10 keys
Your line dict_guy[n_customerID] = { {'clientsName':[], 'company':[], 'contacts':[]}} tried to create a set with a single dictionary in it and because dictionaries are not hashable, you got the TypeError exception informing you that something is not hashable :) (sets can store only ements that are hashable)
Check out this page.
example = {'app_url': '', 'models': [{'perms': {'add': True, 'change': True,
'delete': True}, 'add_url': '/admin/cms/news/add/', 'admin_url': '/admin/cms/news/',
'name': ''}], 'has_module_perms': True, 'name': u'CMS'}