python update dictionary with dictionary in loop - python

I am trying to update a dictionary with an other dictionary in a loop
mainDict = {}
for index in range(3):
tempDict = {}
tempDict['a'] = 1
tempDict['b'] = 2
mainDict.update(tempDict)
Output:
>>> print mainDict
{'a': 1, 'b': 2}
What I am expecting is:
{{'a': 1, 'b': 2},{'a': 1, 'b': 2},{'a': 1, 'b': 2}}
Any suggestions please. Thanks.

Dictionaries are key-value pairs. In your expected output there is no dictionary. Either you want a list, and in this case use:
main_list = []
for (...)
main_list.append(temp_dict)
or add keys in the loop:
mainDict = {}
for index in range(3):
tempDict = {}
tempDict['a'] = 1
tempDict['b'] = 2
mainDict[index] = tempDict

As others commented in the comments section, python dictionaries keys must be unique. Quoting from python docs:
It is best to think of a dictionary as an unordered set of key: value pairs, with the requirement that the keys are unique (within one dictionary)
Possible solution: Create a list instead of a dict to store the dictionaries.

Related

List/Dict comprehension in Python to update a dictionary with keys and values from a string

Does anyone know how to convert below for loop into a list or dictionary comprehension in one line? type(letter) = string,type(stringOne) = string,type(dictResult) = dictionary.For example, stringOne = 'abcddd', I want the output to be dictResult = {'a': 1, 'b': 1, 'c': 1, 'd': 3} Thanks!!!
stringOne = 'abcddd'
dictResult = {}
for letter in stringOne:
dictResult[letter] = dictResult.get(letter,0) + 1
Find unique keys with set and then count. Note the set doesn't not keep (keys) insertion order!
stringOne = 'abcddd'
dictResult = {char: stringOne.count(char) for char in set(stringOne)}
print(dictResult)
Make use of Counter will do. Save you the time to do a loop for the string. Can just convert to dictionary later if you required it to be in dictionary type.
from collections import Counter
counter = Counter(stringOne)
dict(counter)

How to get a particular key value pair from a dict in Python

I have a dict like below
d = {"a":0,"b":1,"c":2}
I need to get only this in my output dict
out = {"b":1}
tried converting the dict to list and accessing the index 1, but it gives me tuples.
Is there any workaround for this
print(list(d.items())[1])
("b",1)
You could do out = {elem:d[elem] for idx,elem in enumerate(d) if idx in [0,1]} to select the indexes in [0,1] but dict([list(d.items())[1]]), as metioned by #Anetropic, works fine as well.
What is the source of your key value? If you want to get all the items in dictionary from a key container:
>>> keys = ['b', 'c']
>>> {key: d[key] for key in keys}
{'b': 1, 'c': 2}
If you just want to get it in order from d.items():
>>> from itertools import islice
>>> dict(islice(d.items(), 1, 3))
{'b': 1, 'c': 2}

Convert a list with duplicating keys into a dictionary and sum the values for each duplicating key

I am new to Python so I do apologize that my first question might not be asked clearly to achieve the right answer.
I thought if I converted a list with duplicating keys into a dictionary then I would be able to sum the values of each duplicating key. I have tried to search on Google and Stack Overflow but I actually still can't solve this problem.
Can anybody help, please? Thank you very much in advance and I truly appreciate your help.
list1 = ["a:2", "b:5", "c:7", "a:8", "b:12"]
My expected output is:
dict = {a: 10, b: 17, c: 7}
You can try this code:
list1 = ["a:2", "b:5", "c:7", "a:8", "b:12"]
l1 = [each.split(":") for each in list1]
d1 = {}
for each in l1:
if each[0] not in d1:
d1[each[0]] = int(each[1])
else:
d1[each[0]] += int(each[1])
d1
Output: {'a': 10, 'b': 17, 'c': 7}
Explanation:
Step 1. Convert your given list to key-value pair by splitting each of the elements in your original list from : and store that in a list/tuple
Step 2. Initialize an empty dictionary
Step 3. Iterate through each key-value pair in the newly created list/tuple and store that in a dictionary. If the key doesn't exist, then add new key-value pair to dictionary or else just add the values to it's corresponding key.
A list does not have "keys" per say, rather it has elements. In your example, the elements them selves are a key value pair. To make the dictionary you want you have to do 3 things,
Parse each element into its key value pair
Handle duplicate values
Add each pair to the dictionary.
the code should look like this
list1 = ["a:2", "b:5", "c:7", "a:8", "b:12"]
dict1={}#make an empty dictionary
for element in list1:
key,value=element.split(':')#This splits your list elements into a tuple of (key,value)
if key in dict1:#check if the key is in the dictionary
dict1[key]+=int(value)#add to existing key
else:
dict1[key]=int(value)#initilize new key
print(dict1)
That code prints out
{'a': 10, 'c': 7, 'b': 17}
You could use a defaultdict, iterate over each string and add the corresponding value after splitting it to a pair (key, value).
>>> from collections import defaultdict
>>> res = defaultdict(int)
>>> for el in list1:
... k, v = el.split(':')
... res[k]+=int(v)
...
>>> res
defaultdict(<class 'int'>, {'a': 10, 'b': 17, 'c': 7})

Retrieving items from a nested dictionary with a nested for loop fresults in KeyError

I need to systematically access dictionaries that are nested within a list within a dictionary at the 3rd level, like this:
responses = {'1': {'responses': [{1st dict to be retrieved}, {2nd dict to be retrieved}, ...]},
'2': {'responses': [{1st dict to be retrieved}, {2nd dict to be retrieved}, ...]}, ...}
I need to unnest and transform these nested dicts into dataframes, so the end result should look like this:
responses = {'1': df1,
'2': df2, ...}
In order to achieve this, I built a for-loop in order to loop through all keys on the first level. Within that loop, I am using another loop to extract each item from the nested dicts into a new empty list called responses_df:
responses_dict = {}
for key in responses.keys():
for item in responses[key]['responses']:
responses_dict[key].update(item)
However, I get:
KeyError: '1'
The inner loop works if I use it individually on a key within the dict, but that doesn't really help me since the data comes from an API and has to be updated dynamically every few minutes in production.
The nex loop to transform the result into dataframes would look like this:
for key in responses_dict:
responses_df[key] = pd.DataFrame.from_dict(responses_dict[key], orient='index')
But I haven't gotten to try that out since the first operation fails.
Try this:
from collections import defaultdict
responses_dict = defaultdict(dict) # instead of {}
Then your code will work.
In fact responses_dict[key] where key=1 doesn't exist.
So when you simply do print(responses_dict[key]) you get the same error, 1 is not a key of that dict and update is not used as it should be.
Try the following syntax :
responses_dict = {}
for key in responses.keys():
print(key)
for item in responses[key]['responses']:
responses_dict.update(key = item)
I prefer using dictionaries while updating a dictionary.
If you update with an existing key, the value of that key will be updated.
If you update with an new key-value pair, the pair will be added to that dictionary.
>>>d1 = {1: 10, 2:20}
>>>d1.update({1:20})
>>>d1
>>>{1: 20, 2:20}
>>>d1.update({3:30})
>>>d1
>>>{1: 20, 2:20, 3:30}
Try fixing your line with:
responses_dict = {}
for key in responses.keys():
for item in responses[key]['responses']:
responses_dict.update({key: item})
So basically, use dictionary to update a dictionary, more readable and easy.
Try this:
responses = {'1': {'responses': [{'a': 1, 'b': 2}, {'c': 3, 'd': 4}]},
'2': {'responses': [{'e': 5}, {'f': 6}]}}
result = {k: pd.DataFrame(chain.from_iterable(v['responses'])) for k, v in responses.items()}
for df in result.values():
print(df, end='\n\n')
Output:
0
0 a
1 b
2 c
3 d
0
0 e
1 f

how to find a match in a dictionary

I have two dictionaries, RFQDict and AwardsDict. I want to take the keys of RFQdict and search through AwardsDict values for matches.
So I tried this
RFQDict = {}
AwardsDict = {}
# Fetch RFQ
RFQref = db.reference('TestRFQ')
snapshot = RFQref.get()
for key, val in snapshot.items():
RFQDict[key] = val
print('{0} => {1}'.format(key, val))
Awardsref = db.reference('DibbsAwards')
dsnapshot = Awardsref.get()
for key, val in dsnapshot.items():
AwardsDict[key] = val
print('{0} => {1}'.format(key, val))
for key in RFQDict:
if key in AwardsDict.values():
print(key+ " Match found")
is this the way to do it or there is a better way and how could return the key and values where the match was found?
In python3 you can do AwardsDict.values() & RFQDict.keys() and you will get a set with the common key/values.
The '&' operator is used for set intersection and works with the dictionary views returned by values() and keys(). More information of the view returned by those methods: https://docs.python.org/3/library/stdtypes.html?highlight=dictview#dictionary-view-objects
If you want to store the keys and values that match, it would probably be best to store the key and value from the second dictionary since if you just store the matching key and value you will have elements like (a, a) which won't really tell you much about where they matched in the second dictionary. Maybe something like this
d1 = {'a': 1, 'b': 2, 'c': 3}
d2 = {'x': 'a', 'y': 1, 'z': 'c'}
res = [(i, {j: d2[j]}) for i in d1 for j in d2 if i == d2[j]]
print(res)
# [('a': {'x': 'a'}), ('c': {'z': 'c'})]
I would do a list comprehension:
result=[x for x in AwardsDict.values() if x in RFQDict.keys() ]
This way you get a list keeping the duplicates. That is, if a RFQ key is presented in more than one value in AwardsDict. With the & operator you loss that information (as sets only have unique elements).
For example:
RFQDict = {}
AwardsDict = {}
for i in range(5):
RFQDict[i]=0
for i in range(5):
AwardsDict[i]=i
for i in range(5,11):
AwardsDict[i]=i//2 #integer division, i=8 and i=9 get a value of 4
result=[x for x in AwardsDict.values() if x in RFQDict.keys() ]
print('{}'.format(result))
#output [0, 1, 2, 3, 4, 2, 3, 3, 4, 4]

Categories

Resources