Problem inputting several lists to dictionary values - python

Stackoverflow, hello
I have a big problem with inputting a several list into multiple values
Initial code is:
animal_book={}
animal_type=['herbivorous', 'carnivorous']
animal_name=[['Elephant', 'Cow', 'Deer'], ['Tiger', 'Lion', 'Puma']]
animal_quantity=[[1, 2, 3], [4, 5, 6]]
animal_age=[['50','10','5'],['6', '7', '8']]
j=0
k=0
for i in animal_type:
animal_book[i]=[{'type':animal_name[j][k], 'name': animal_quantity[j][k], 'age':animal_age[j][k]}]
j += 1
print(animal_book)
The result I have is almost what I need, but with only one first compound in a animal_book value, not the several dictionaries, as I wanted (I've separated it by lines manually for better look):
>>{'herbivorous': [
{'name': 'Elephant', 'quantity': 1, 'age': '50'}
],
'carnivorous': [
{'name': 'Tiger', 'quantity': 4, 'age': '6'}
]
}
However, my aim here is to put these list into multiple values of the dictionary. Required code is:
{'herbivorous': [
{'name': 'Elephant', 'quantity': 1, 'age': '50'},
{'name': 'Cow', 'quantity': 2, 'age': '10'},
{'name': 'Deer', 'quantity': 3, 'age': '5'},
],
'carnivorous':[
{'name': 'Tiger', 'quantity': 4, 'age': '6'}
{'name': 'Lion', 'quantity': 5, 'age': '7'}
{'name': 'Puma', 'quantity': 6, 'age': '8'}
]
}
Does everybody know how to solve the problem?
I've tried to add the lists to animal_book.values() also after the for i in animal_type:
animal_book[i]=animal_book.values().append([{'name':animal_name[j][k], 'quantity': animal_quantity[j][k], 'age':animal_age[j][k]}])
But in this case I have an error: AttributeError: 'dict_values' object has no attribute 'append'

First Mistake :you are getting only one result because you are over-writing the dictionary value each time with the list .
Second Mistake : You are increasing j by one and looping through the animal type list which has 2 elements that means only two elements will be in the dictionary.
from pprint import pprint
animal_book={}
animal_type=['herbivorous', 'carnivorous']
animal_name=[['Elephant', 'Cow', 'Deer'], ['Tiger', 'Lion', 'Puma']]
animal_quantity=[[1, 2, 3], [4, 5, 6]]
animal_age=[['50','10','5'],['6', '7', '8']]
for j in range(len(animal_type)):
value_list = []
for k in range(len(animal_name[j])):
value_list.append({'type':animal_quantity[j][k], 'name': animal_name[j][k], 'age':animal_age[j][k]})
animal_book.update({animal_type[j]: value_list})
pprint(animal_book)
Output:
{'carnivorous': [{'age': '6', 'name': 'Tiger', 'type': 4},
{'age': '7', 'name': 'Lion', 'type': 5},
{'age': '8', 'name': 'Puma', 'type': 6}],
'herbivorous': [{'age': '50', 'name': 'Elephant', 'type': 1},
{'age': '10', 'name': 'Cow', 'type': 2},
{'age': '5', 'name': 'Deer', 'type': 3}]}

You can use zip to arrange your data in a suiteable manner and fill your book with that:
animal_book ={}
animal_type=['herbivorous', 'carnivorous']
animal_name=[['Elephant', 'Cow', 'Deer'], ['Tiger', 'Lion', 'Puma']]
animal_quantity=[[1, 2, 3], [4, 5, 6]]
animal_age=[['50','10','5'],['6', '7', '8']]
# zip your data together, extract the typ again, put the remainder into R
for typ, *R in zip(animal_type, animal_name, animal_quantity, animal_age):
# add the typ-list
animal_book.setdefault(typ,[])
# now handle the inner dicts data that have to be added to your lists
# first create tuples for each animal as r
for r in zip(*R):
# then create tuples of (key,value) and make dicts from it
animal_book[typ].append(dict(zip(["name","quantity","age"],r)))
# pretty print it
from pprint import pprint
pprint(animal_book)
Output:
{'carnivorous': [{'age': '6', 'name': 'Tiger', 'quantity': 4},
{'age': '7', 'name': 'Lion', 'quantity': 5},
{'age': '8', 'name': 'Puma', 'quantity': 6}],
'herbivorous': [{'age': '50', 'name': 'Elephant', 'quantity': 1},
{'age': '10', 'name': 'Cow', 'quantity': 2},
{'age': '5', 'name': 'Deer', 'quantity': 3}]}
R looks like this:
[['Elephant', 'Cow', 'Deer'], [1, 2, 3], ['50', '10', '5']]
[['Tiger', 'Lion', 'Puma'], [4, 5, 6], ['6', '7', '8']]
and r look like this:
('Elephant', 1, '50')
('Cow', 2, '10')
('Deer', 3, '5')
('Tiger', 4, '6')
('Lion', 5, '7')
('Puma', 6, '8')
and zip(["name","quantity","age"],r) looks approximately like so:
[('name', 'Elephant'), ('quantity', 1), ('age', '50')]
[('name', 'Cow'), ('quantity', 2), ('age', '10')]
[('name', 'Deer'), ('quantity', 3), ('age', '5')]
[('name', 'Tiger'), ('quantity', 4), ('age', '6')]
[('name', 'Lion'), ('quantity', 5), ('age', '7')]
[('name', 'Puma'), ('quantity', 6), ('age', '8')]

Here you go, this solves your problem. You have to have one for loop nested inside another one and use enumerate so you can keep track of the index. Also, if you use json.dumps() it will pretty-print a dictionary for you.
import json
animal_type=['herbivorous', 'carnivorous']
animal_name=[['Elephant', 'Cow', 'Deer'], ['Tiger', 'Lion', 'Puma']]
animal_quantity=[[1, 2, 3], [4, 5, 6]]
animal_age=[['50','10','5'],['6', '7', '8']]
animal_book={}
for index, type in enumerate(animal_type):
animal_book[type] = []
for jdex, animal in enumerate(animal_name[index]):
animal_book[type].append({
'name': animal,
'quantity': animal_quantity[index][jdex],
'age': animal_age[index][jdex],
})
print(json.dumps(animal_book, indent=2))
This will output:
{
"herbivorous": [
{
"name": "Elephant",
"quantity": 1,
"age": "50"
},
{
"name": "Cow",
"quantity": 2,
"age": "10"
},
{
"name": "Deer",
"quantity": 3,
"age": "5"
}
],
"carnivorous": [
{
"name": "Tiger",
"quantity": 4,
"age": "6"
},
{
"name": "Lion",
"quantity": 5,
"age": "7"
},
{
"name": "Puma",
"quantity": 6,
"age": "8"
}
]
}

You should use the range function to iterate over the items in more systematic way:
animal_book={}
animal_type=['herbivorous', 'carnivorous']
animal_name=[['Elephant', 'Cow', 'Deer'], ['Tiger', 'Lion', 'Puma']]
animal_quantity=[[1, 2, 3], [4, 5, 6]]
animal_age=[['50','10','5'],['6', '7', '8']]
for i in range(len(animal_type)):
for j in range(len(animal_name[i])):
animal_book[i]=[{'type':animal_name[i][j], 'name': animal_quantity[i][j], 'age':animal_age[i][j]}]
print(animal_book)

Related

How to convert this loops into list comprehension?

I want to convert these loops into a list comprehension but I don't know how to do it. Can anyone help me pls?
this is the list i want to convert:
students = ['Tommy', 'Kitty', 'Jessie', 'Chester', 'Curie', 'Darwing', 'Nancy', 'Sue',
'Peter', 'Andrew', 'Karren', 'Charles', 'Nikhil', 'Justin', 'Astha','Victor',
'Samuel', 'Olivia', 'Tony']
assignment = [2, 5, 5, 7, 1, 5, 2, 7, 5, 1, 1, 1, 2, 1, 5, 2, 7, 2, 7]
x = list(zip(students, assignment))
Output = {}
for ke, y in x:
y = "Group {}".format(y)
if y in Output:
Output[y].append((ke))
else:
Output[y] = [(ke)]
print(Output)
this what I have tried:
{Output[y].append((ke)) if y in Output else Output[y]=[(ke)]for ke, y in x}
You could do this with a nested dictionary/list comprehension:
Output = { f'Group {group}' : [ name for name, g in x if g == group ] for group in set(assignment) }
Output:
{
'Group 2': ['Tommy', 'Nancy', 'Nikhil', 'Victor', 'Olivia'],
'Group 5': ['Kitty', 'Jessie', 'Darwing', 'Peter', 'Astha'],
'Group 7': ['Chester', 'Sue', 'Samuel', 'Tony'],
'Group 1': ['Curie', 'Andrew', 'Karren', 'Charles', 'Justin']
}
data1 = {'students': ['Tommy', 'Kitty', 'Jessie', 'Chester', 'Curie', 'Darwing', 'Nancy', 'Sue',
'Peter', 'Andrew', 'Karren', 'Charles', 'Nikhil', 'Justin', 'Astha','Victor',
'Samuel', 'Olivia', 'Tony'],
'assignment': [2, 5, 5, 7, 1, 5, 2, 7, 5, 1, 1, 1, 2, 1, 5, 2, 7, 2, 7]}
df1 = pd.DataFrame(data1)
df1.groupby('assignment')['students'].agg(set).to_dict()
Output
{1: {'Andrew', 'Charles', 'Curie', 'Justin', 'Karren'},
2: {'Nancy', 'Nikhil', 'Olivia', 'Tommy', 'Victor'},
5: {'Astha', 'Darwing', 'Jessie', 'Kitty', 'Peter'},
7: {'Chester', 'Samuel', 'Sue', 'Tony'}}
You want a dict comprehension which will create a dict whose values come from a list comprehension.
itertools.groupby can help:
from itertools import groupby
x = sorted(list(zip(assignment, students)))
out = {f'Group {x}':[z[1] for z in y] for x,y in groupby(x, lambda y:y[0])}
{'Group 1': ['Andrew', 'Charles', 'Curie', 'Justin', 'Karren'], 'Group 2': ['Nancy', 'Nikhil', 'Olivia', 'Tommy', 'Victor'], 'Group 5': ['Astha', 'Darwing', 'Jessie', 'Kitty', 'Peter'], 'Group 7': ['Chester', 'Samuel', 'Sue', 'Tony']}

jmespath search nested array issue

I need to search all dict in a nested array as below by its key with jmespath
my_list = [[{'age': 1, 'name': 'kobe'}, {'age': 2, 'name': 'james'}], [{'age': 3, 'name': 'kobe'}]]
I got an empty list with jmespath search: jmespath.search("[][?name=='kobe']", my_list)
how can I get result: [{'age': 1, 'name': 'kobe'}, {'age': 3, 'name': 'kobe'}] with jmespath search
Use the following jmesQuery:
[]|[?name=='kobe']
on input:
[[{"age": 1, "name": "kobe"}, {"age": 2, "name": "james"}], [{"age": 3, "name": "kobe"}]]
to get output:
[
{
"age": 1,
"name": "kobe"
},
{
"age": 3,
"name": "kobe"
}
]
The problem here is that you have a mix of different types, that is why you don't get expected results.
What you should do is this:
jmespath.search("[].to_array(#)[?name=='kobe'][]", my_list)
Here is a break down using Python console (pay attention to :
>>> my_list
[[{'age': 1, 'name': 'kobe'}, {'age': 2, 'name': 'james'}], [{'age': 3, 'name': 'kobe'}]]
>>> jmespath.search("[]", my_list)
[{'age': 1, 'name': 'kobe'}, {'age': 2, 'name': 'james'}, {'age': 3, 'name': 'kobe'}]
>>> jmespath.search("[].to_array(#)", my_list)
[[{'age': 1, 'name': 'kobe'}], [{'age': 2, 'name': 'james'}], [{'age': 3, 'name': 'kobe'}]]
>>> jmespath.search("[].to_array(#)[]", my_list)
[{'age': 1, 'name': 'kobe'}, {'age': 2, 'name': 'james'}, {'age': 3, 'name': 'kobe'}]
>>> jmespath.search("[].to_array(#)[?name=='kobe']", my_list)
[[{'age': 1, 'name': 'kobe'}], [], [{'age': 3, 'name': 'kobe'}]]
>>> jmespath.search("[].to_array(#)[?name=='kobe'][]", my_list)
[{'age': 1, 'name': 'kobe'}, {'age': 3, 'name': 'kobe'}]
You can find more explanation with examples in this guide: https://www.doaws.pl/blog/2021-12-05-how-to-master-aws-cli-in-15-minutes/how-to-master-aws-cli-in-15-minutes
Use Below code:
my_list = [[{'age': 1, 'name': 'kobe'}, {'age': 2, 'name': 'james'}], [{'age': 3,
'name': 'kobe'}]]
for l in my_list:
for dictionary in l:
Value_List = dictionary.values()
if "kobe" in Value_List:
print(dictionary)
Output:
{'age': 1, 'name': 'kobe'}
{'age': 3, 'name': 'kobe'}
OR-----
my_list = [[{'age': 1, 'name': 'kobe'}, {'age': 2, 'name': 'james'}],
[{'age': 3, 'name': 'kobe'}]]
Match_List = []
for l in my_list:
for dictionary in l:
if dictionary["name"] == "kobe":
Match_List.append(dictionary)
print(Match_List)
Output:
[{'age': 1, 'name': 'kobe'}, {'age': 3, 'name': 'kobe'}]

how to create a list that will store many values from a list of dictionaries

I have a list of Dictionaries in which airbnb[0] is
{
'room_id': '1133718',
'survey_id': '1280',
'host_id': '6219420',
'room_type': 'Shared room',
'country': '',
'city': 'Singapore',
'borough': '',
'neighborhood': 'MK03',
'reviews': 9.0,
'overall_satisfaction': 4.5,
'accommodates': '12',
'bedrooms': '1.0',
'bathrooms': '',
'price': 74.0,
'minstay': '',
'last_modified': '2017-05-17 09:10:25.431659',
'latitude': 1.293354,
'longitude': 103.769226,
'location': '0101000020E6100000E84EB0FF3AF159409C69C2F693B1F43F'
}
how do I go about it if I want to get a list consisting of only the room_id Value and the price for each dictionary in my list of dictionaries so that I can compile those lists in my new_list?
Not sure if this is what you're after but you can make a dictionary where the key is the room_id and the value the price for each property like so:
room_prices = { room['room_id'] : room['price'] for room in airbnb }
Then you access the price for a given room like so:
room_id = '1133718'
room_price = room_prices[room_id]
If you want them as tuples:
new_list = [(x['room_id'], x['price']) for x in airbnb]
# returns
[('1133718', 74.0)]
or a dict:
new_list = [{'room_id': x['room_id'], 'price': x['price']} for x in airbnb]
# returns
[{'room_id': '1133718', 'price': 74.0}]
A list comprehension selecting target keys in your list of dictionaries should do the job, assuming your list contains multiple dictionaries.
room_info =[{
'room_id': '1133718',
'survey_id': '1280',
'host_id': '6219420',
'room_type': 'Shared room',
'country': '',
'city': 'Singapore',
'borough': '',
'neighborhood': 'MK03',
'reviews': 9.0,
'overall_satisfaction': 4.5,
'accommodates': '12',
'bedrooms': '1.0',
'bathrooms': '',
'price': 74.0,
'minstay': '',
'last_modified': '2017-05-17 09:10:25.431659',
'latitude': 1.293354,
'longitude': 103.769226,
'location': '0101000020E6100000E84EB0FF3AF159409C69C2F693B1F43F'
},
{
'room_id': '1133718',
'survey_id': '1280',
'host_id': '6219420',
'room_type': 'Shared room',
'country': '',
'city': 'Singapore',
'borough': '',
'neighborhood': 'MK03',
'reviews': 9.0,
'overall_satisfaction': 4.5,
'accommodates': '12',
'bedrooms': '1.0',
'bathrooms': '',
'price': 74.0,
'minstay': '',
'last_modified': '2017-05-17 09:10:25.431659',
'latitude': 1.293354,
'longitude': 103.769226,
'location': '0101000020E6100000E84EB0FF3AF159409C69C2F693B1F43F'
}]
[[i['room_id'],i['price']] for i in room_info]
>>[['1133718', 74.0], ['1133718', 74.0]]
The result will return a nested list where each individual list contains the room_id and price detail.
It's easy to extract one element of the dict into a new list:
room_ids = [item.get('room_id') for item in airbnb]
Do that for all interesting ones and generate a new list of dicts, if you don't want separate lists. Or you can do all that in one loop
newlist = [{'room_id': item.get('room_id'), 'price': item.get('price')} for item in airbnb]
EDIT: Or a bit more verbose but more general:
mylist = [{'a': 1, 'b':2, 'c':1}, {'a': 2, 'b': 2, 'c':1}, {'a': 5, 'b': 2, 'c':1}, {'b': 5}]
interesting_keys = ['a', 'b']
newlist = []
for item in mylist:
d = dict()
for i in interesting_keys:
d[i] = item.get(i)
newlist.append(d)
print(nl)
will output:
[{'a': 1, 'b': 2}, {'a': 2, 'b': 2}, {'a': 5, 'b': 2}, {'a': None, 'b': 5}]

How to remove a json string from list in python

I have two list with particular data I would like to merge them into a single list with out duplicates.
list1 =[{"id": "123","Name": "Sam", "Age": 10},{"id": "124","Name": "Ajay", "Age": 10}]
list2 =[{"id": "123","Name": "Sam"},{"id": "124","Name": "Ajay"},{"id": "125","Name": "Ram"}]
The output list should be like this
output= [{"id": "123","Name": "Sam", "Age": 10},{"id": "124","Name": "Ajay", "Age": 10},{"id": "125","Name": "Ram"}]
Presumably it is the id key that uniquely identifies the information. If so, collect all the info from the two lists in a dictionary, then produce a new list from that:
from itertools import chain
per_id = {}
for info in chain(list1, list2):
per_id.setdefault(info['id'], {}).update(info)
output = list(per_id.values()) # Python 2 and 3 compatible
Demo:
>>> from itertools import chain
>>> list1 = [{'Age': 10, 'id': '123', 'Name': 'Sam'}, {'Age': 10, 'id': '124', 'Name': 'Ajay'}]
>>> list2 = [{'id': '123', 'Name': 'Sam'}, {'id': '124', 'Name': 'Ajay'}, {'id': '125', 'Name': 'Ram'}]
>>> per_id = {}
>>> for info in chain(list1, list2):
... per_id.setdefault(info['id'], {}).update(info)
...
>>> list(per_id.values())
[{'Age': 10, 'id': '123', 'Name': 'Sam'}, {'Age': 10, 'id': '124', 'Name': 'Ajay'}, {'id': '125', 'Name': 'Ram'}]

Python: Convert a list into a bidimensional mapping dictionary

I have a list of dictionaries:
[
{'student_id': 'john', 'exercise_id': '3', 'answer': 20},
{'student_id': 'john', 'exercise_id': '2', 'answer': 10},
{'student_id': 'jane', 'exercise_id': '2', 'answer': 30},
]
What is an elegant/short way to convert that into a [exercise x student] "mapping table" dictionary?
Like so:
{
'3':{
'john': {'student_id': 'john', 'exercise_id': '3', 'answer': 20}
},
'2': {
'john': {'student_id': 'john', 'exercise_id': '2', 'answer': 10},
'jane': {'student_id': 'jane', 'exercise_id': '2', 'answer': 30}
}
}
You can assume the map contains at most one answer per exercise per student.
The straight forward way would be to gather them in a dictionary, like this
d = {}
for item in l:
d.setdefault(item["exercise_id"], {}).setdefault(item["student_id"], []).append(item)
print(d)
Output
{'2': {'jane': [{'answer': 30, 'exercise_id': '2', 'student_id': 'jane'}],
'john': [{'answer': 10, 'exercise_id': '2', 'student_id': 'john'}]},
'3': {'john': [{'answer': 20, 'exercise_id': '3', 'student_id': 'john'}]}}
First, if the item["exercise_id"] is not there in d, then a new dictionary will be set as the value and then in that dictionary, if item["student_id"] is not there, we set an empty list as the value and we append the current dictionary in that list.
This generates the output you want:
output = {}
for value in data:
output.setdefault(value['exercise_id'], {})[value['student_id']] = value
print output

Categories