How to append items from a list into a dictionary? - python

I'm very new to programming and Python and trying to figure things out. I'm trying to take items out of a list and append the keys and values to a dictionary but I can't figure out how. I tried using the dictionary's Update method but I'm only getting the last item from my list, not all the items. Here is my code:
a = {}
names = [ {'name': 'Bart'}, {'name': 'Lisa'}, {'name': 'Maggie'} ]
for name in names:
a.update(name)
The result I'm getting back is:
{'name': 'Maggie'}
But I want this in my new dictionary:
{'name': 'Bart'}, {'name': 'Lisa'}, {'name': 'Maggie'}
I wanted to put the items from the list inside the dictionary in order to access the values. I need all of the names but maybe there is a much easier way to do it.
Any hints would be great. Thanks.

With same key value you cant update a dict from list of dict. You can get a dict with key a list of values.
{'name': ['Bart', 'Lisa', 'Maggie']}
a={}
for n in names:
... for k in n:
... for k,v in [(k,n[k])]:
... if k not in a:a[k]=[v]
... else: a[k].append(v)

Related

Returning a list of dictionaries by iterating over given data

So let's say I've a list of students and there is a dictionary containing some data for each student as given below :
students= [{'student_name': 'name1',
'regNO': '12',
},{'student_name': 'name2',
'regNO': '13',
},{'student_name': 'name3',
'regNO': '14',
}
]
So based on the above data I want to return another list of dictionaries containing data for each student,
I wrote the following code :
res_dict = {}
res_list = []
for student in students:
res_dict['name']=student['student_name']
res_list.append(res_dict)
print(res_list)
I was hoping that in the output, for each student , there would be a dictionary with key being 'name' and value being the student name taken from 'students' list. I expected it to be as follows :
[{'name': 'name1'}, {'name': 'name2'}, {'name': 'name3'}]
But the output turned out to be this :
[{'name': 'name3'}, {'name': 'name3'}, {'name': 'name3'}]
Can anyone help me identify the issue in my code ?
The better way to get the desired result is via using list comprehension expression as:
[{'name': student['student_name']} for student in students]
The issue with your code is you are updating the values in same reference of the dict object and appending the same object again to the list. Change your code to:
for student in students:
res_dict = {} # Create new `dict` object
res_dict['name'] = student['student_name']
res_list.append(res_dict)
OR, you may just do:
for student in students:
res_list.append({'name': student['student_name']})
The subtle concept of list is that it does not copy the item that you append to it.Instead of that it just stores the pointer to the newly added object via append,similar to pointer arrays in c.So when you try print(res_dict),it will give you the the result like this [{'name': 'name3'}, {'name': 'name3'}, {'name': 'name3'}].But when you append this to the list,all the items in the list point to the same object.You can verify this by this small fragment of code
for i in res_list:
print(id(i))
You will find the same memory address for all the list elements.
But when you take a copy of the dictionary with the help of d.copy() and append that to the res_list,you can see that all the list objects are pointing to different objects by the same technique using id(i) and for loop as shown above.
So finally the corrected code would be
students= [{'student_name': 'name1',
'regNO': '12',
},{'student_name': 'name2',
'regNO': '13',
},{'student_name': 'name3',
'regNO': '14',
}
]
res_dict = {}
res_list = []
for student in students:
res_dict['name']=student['student_name']
res_list.append(res_dict.copy())
print(res_list)
Using list comprehension would always expose the contents to be modified.
This is a classic reference issue. In other words you are appending the reference to the same dict object. Thus, when you change the name value on it, for all times it shows up in the list it will reflect its new value. Instead, create a new dict for each iteration and append that :)
Here is a simple way to do it.
n_list = [{'name':i['student_name']} for i in students]
You should reset res_dict = {} to an empty dict within your loop for each new entry.

insert key-pair value into nested dict without overwriting after delimiter of key which produce duplicate key

Assume that I have a nested dict like:
D={'Germany': {'1972-05-23': 'test1', '1969-12-27': 'test2'},
'Morocco|Germany': {'1978-01-14':'test3'}}
I want to get a new dict like:
{'Germany': {'1972-05-23': 'test1', '1969-12-27': 'test2', '1978-01-14':'test3'}
'Morocco': {'1978-01-14':'test3'}}
which means I have to handle the perhaps duplicate key after the str.split(key) ,and this is my code:
D={'Germany': {'1972-05-23': 'test1', '1969-12-27': 'test2'},
'Morocco|Germany': {'1978-01-14':'test3'}}
new_dict={}
for item in D:
for index in str.split(item,'|'):
new_dict[index]=D[item]
print new_dict
however the key-value pair generated after splitting operation overwriting the original ones which result:
{'Morocco': {'1978-01-14': 'test3'}, 'Germany': {'1978-01-14': 'test3'}}
I wonder how I can modify the my code to get a satisfying dict for further processing or any better solution for this requirement?
PS: My Python Version is 2.7.12 with Anaconda 4.0.0 via IDE PyCharm
Any help will be appreciated, thank you
you could use:
if not index in new_dict: new_dict[index] = {}
new_dict[index].update(D[item])

Ordering a nested dictionary in python

I have a nested dictionary (category and subcategories), dict, that I am having trouble sorting.
The output of dict is:
{u'sports': {u'basketball': {'name': u'Basketball', 'slug': u'basketball'}, u'baseball': {'name': u'Baseball', 'slug': u'baseball'}}, u'dance': {u'salsa': {'name': u'Salsa', 'slug': u'salsa'}}, u'arts': {u'other-5': {'name': u'Other', 'slug': u'other-5'}, u'painting': {'name': u'Painting', 'slug': u'painting'}}, u'music': {u'cello': {'name': u'Cello', 'slug': u'cello'}, u'accordion': {'name': u'Accordion', 'slug': u'accordion'}}}
How can I sort this dictionary so that the 'other' subcategory always shows up at the end of the nested dictionary. For example the order for the "arts" category should be:
..., u'arts': {u'painting': {'name': u'Painting', 'slug': u'painting'}, u'other-5': {'name': u'Other', 'slug': u'other-5'}}...
You have some major concept misunderstanding about dictionary. Dictionary in python is like a hash table, hash table has no order. The output of the dict is really environment dependent so you couldn't depend on that. You might see one way of the output while other people see another way. You should consider using OrderedDict instead.
Python dictionaries (regular dict instances) are not sorted. If you want to sort your dict, you could:
from collections import OrderedDict
mynewdict = OrderedDict(sorted(yourdict.items()))
An OrderedDict does not provide a sorting mechanism, but only respect the order of the keys being inserted on it (we sort those keys calling sorted beforehand).
Since you need a specific criteria (lets say your keys are alphabetically ordered except for the "other" key which goes to the end), you need to declare it:
def mycustomsort(key):
return (0 if key != 'other' else 1, key)
mynewdict = OrderedDict(sorted(yourdict.items(), key=mycustomsort))
This way you are creating a tuple for the nested criteria: the first criteria is other vs. no-other, and so the 0 or 1 (since 1 is greater, other comes later), while the second criteria is the key itself. You can remove the second criteria and not return a tuple if you want, but only the 0 and 1, and the code will work without alphabetical sort.
This solution will not work if you plan to edit the dictionary later, and there is no standard class supporting that.

How do I turn list values into an array with an index that matches the other dic values?

Hoping someone can help me out. I've spent the past couple hours trying to solve this, and fair warning, I'm still fairly new to python.
This is a repost of a question I recently deleted. I've misinterpreted my code in the last example.The correct example is:
I have a dictionary, with a list that looks similar to:
dic = [
{
'name': 'john',
'items': ['pants_1', 'shirt_2','socks_3']
},
{
'name': 'bob',
items: ['jacket_1', 'hat_1']
}
]
I'm using .append for both 'name', and 'items', which adds the dic values into two new lists:
for x in dic:
dic_name.append(dic['name'])
dic_items.append(dic['items'])
I need to split the item value using '_' as the delimiter, so I've also split the values by doing:
name, items = [i if i is None else i.split('_')[0] for i in dic_name],
[if i is None else i.split('_')[0] for i in chain(*dic_items)])
None is used in case there is no value. This provides me with a new list for name, items, with the delimiter used. Disregard the fact that I used '_' split for names in this example.
When I use this, the index for name, and item no longer match. Do i need to create the listed items in an array to match the name index, and if so, how?
Ideally, I want name[0] (which is john), to also match items[0] (as an array of the items in the list, so pants, shirt, socks). This way when I refer to index 0 for name, it also grabs all the values for items as index 0. The same thing regarding the index used for bob [1], which should match his items with the same index.
#avinash-raj, thanks for your patience, as I've had to update my question to reflect more closely to the code I'm working with.
I'm reading a little bit between the lines but are you trying to just collapse the list and get rid of the field names, e.g.:
>>> dic = [{'name': 'john', 'items':['pants_1','shirt_2','socks_3']},
{'name': 'bob', 'items':['jacket_1','hat_1']}]
>>> data = {d['name']: dict(i.split('_') for i in d['items']) for d in dic}
>>> data
{'bob': {'hat': '1', 'jacket': '1'},
'john': {'pants': '1', 'shirt': '2', 'socks': '3'}}
Now the data is directly related vs. indirectly related via a common index into 2 lists. If you want the dictionary split out you can always
>>> dic_name, dic_items = zip(*data.items())
>>> dic_name
('bob', 'john')
>>> dic_items
({'hat': '1', 'jacket': '1'}, {'pants': '1', 'shirt': '2', 'socks': '3'})
You need a list of dictionaries because the duplicate keys name and items are overwritten:
items = [[i.split('_')[0] for i in d['items']] for d in your_list]
names = [d['name'] for d in your_list] # then grab names from list
Alternatively, you can do this in one line with the built-in zip method and generators, like so:
names, items = zip(*((i['name'], [j.split('_')[0] for j in i['items']]) for i in dic))
From Looping Techniques in the Tutorial.
for name, items in div.items():
names.append(name)
items.append(item)
That will work if your dict is structured
{'name':[item1]}
In the loop body of
for x in dic:
dic_name.append(dic['name'])
dic_items.append(dic['items'])
you'll probably want to access x (to which the items in dic will be assigned in turn) rather than dic.

Python Dictionary - List Nesting

I have a dictionary with a key and a pair of values, the values are stored in a List. But i'm keeping the list empty so i can .append its values ,i cant seem to be able to do this
>>>myDict = {'Numbers':[]}
>>>myDict['Numbers'[1].append(user_inputs)
doesn't seem to work, returns an error . How do i refer to the list in myDict so i can append its values.
Also is it possible to have a dictionary inside a list and also have another list inside? if so? what is its syntax or can you recommend anyother way i can do this
>>>myDict2 = {'Names': [{'first name':[],'Second name':[]}]}
do i change the second nested list to a tuple?? Please lets keep it to PYTHON 2.7
You get an error because your syntax is wrong. The following appends to the list value for the 'Numbers' key:
myDict['Numbers'].append(user_inputs)
You can nest Python objects arbitrarily; your myDict2 syntax is entirely correct. Only the keys need to be immutable (so a tuple vs. a list), but your keys are all strings:
>>> myDict2 = {'Names': [{'first name':[],'Second name':[]}]}
>>> myDict2['Names']
[{'first name': [], 'Second name': []}]
>>> myDict2['Names'][0]
{'first name': [], 'Second name': []}
>>> myDict2['Names'][0]['first name']
[]
You should access the list with myDict['Numbers']:
>>>myDict['Numbers'].append(user_inputs)
You can have dicts inside of a list.
The only catch is that dictionary keys have to be immutable, so you can't have dicts or lists as keys.
You may want to look into the json library, which supports a mix of nested dictionaries and lists.
In addition, you may also be interested in the setdefault method of the dictionary class.
Format is something like:
new_dict = dict()
some_list = ['1', '2', '3', ...]
for idx, val in enumerate(some_list):
something = get_something(idx)
new_dict.setdefault(val, []).append(something)

Categories

Resources