Add dictionary as value of dictionary in Python - python

I want to create a array of set in Python.
That is what i am trying to do with my code below
for doc in collection.find():
pageType = doc.get('pageType')
title = doc.get('title')
_id = doc.get('_id')
value = {'pageType' : pageType, 'id': _id}
setValues = pageDict.get(title)
if not setValues :
setValues = set()
pageDict[title] = setValues
setValues.add(value)
I get following error when running it
setValues.add(value)
TypeError: unhashable type: 'dict'
I found that i cannot set the mutable value as a key of the dictionary, but i am here adding it as value of dictionary. Essentially, my value of dictionary is a set which contains another dictionary.
How can i achieve this in python? What other data structures can i used to achieve this?

i used frozsenSet to add the value to the set and it worked
setValues.add(frozenSet(value.items())

Related

Python TypeError: unhashable type: 'slice' in dictionary

I am getting this TypeError in this simple code, appending a value to a dictionary.
dict = {}
dict['key' : 'value']
print(dict)
dict = {}
dict['key'] = 'value'
print(dict)
[index1 :index2 ] is list slice operation, which will not work on dict
well you can do much more
d={}
for appending to it you can do
d={'key1':'value1','key2':'value'}
also
d.update(key3:'val3')
hope this helps
You can't add like this, it's a dictionary that takes key and value as a separate entity like
dict['key'] = 'value'
After doing this, the dictionary will automatically convert itself like-
dict['key' : 'value']

How to access the value from nested dictionary in Python

I have this kind of dictionary:
{"Odds":{"Home-Win": {"Name-BookMaker":{A:value}}}
This structure is saved inside my pickle and I want to access the element called value, with the for loop iterate over the pickle:
for match in name_of_the_pickle:
odds = match.get("Odds")
home_win = odds.get("Home-Win").values()
but with this last instruction my output is the following:
"dict_values([{A:value}])"
But what I want is only "value", how can I do this?
Ok I found a working example for te instance you gave us based on casting the dict_values object to a list:
odds = match.get("Odds")
home_win = list(odds.get("Home-Win").values())[0]
At this point home_win looks like this:
{'A': 'value'}
Then to retrieve 'value', you could call values() again:
val = list(home_win.values())[0]
print(val)
>>>'value'

Casting a value in a dictionary from str to float

I have been trying to look at other questions and not found anything that works for me. I have a list if dictionaries (trips) and want to access the values in each dictionary within the list of trips, and convert if from a string to a float.
If i take trips[0] output is:
# {'pickup_latitude': '40.64499',
# 'pickup_longitude': '-73.78115',
# 'trip_distance': '18.38'}
I am trying to build a function that iterates through the list of dictionaries, accessing the values and transferring them to floats.
I have tried various versions of the code below, including trying to build a new dictionary and returning that
def float_values(trips):
for trip in trips:
for key, value in trip.items():
value = float(value)
return
float_values[0] should output:
# {'pickup_latitude': 40.64499,
# 'pickup_longitude': -73.78115,
# 'trip_distance': 18.38}
Continuously getting
'function' object is not subscriptable'
OR
'NoneType' object is not subscriptable
If you what to override your values from the dictionary you should do something like this
def float_values(trips):
for trip in trips:
for key, value in trip.items():
trip[key] = float(value)
return trips
By doing value = float(value) you are writing temporary the float value and not saving it anywhere
Simply what you need to do is change value inside the dictionary:
for list_dict in list_of_dicts:
for key, value in list_dict.items():
list_dict[key] = float(value)

Store Widgets in Dictionary

I would like to store my various checkboxes in a dictionary so that I can later call upon them. Since I would like to perform actions based on the number of widgets with len(self.il['Line2']) I need some way of storing them all in an array. Storing each of widgets in a unique entry like:
for i in range(7): #INPUT LINE 2
self.il['Line2',i] = QtWidgets.QCheckBox(self.il2info[i],self)
print(self.il['Line2',i])
--------output----------
<PyQt5.QtWidgets.QCheckBox object at 0x0000021A4398EE58>
<PyQt5.QtWidgets.QCheckBox object at 0x0000021A4398EF78>
<PyQt5.QtWidgets.QCheckBox object at 0x0000021A439690D8>
<PyQt5.QtWidgets.QCheckBox object at 0x0000021A43969168>
<PyQt5.QtWidgets.QCheckBox object at 0x0000021A439691F8>
<PyQt5.QtWidgets.QCheckBox object at 0x0000021A43969288>
<PyQt5.QtWidgets.QCheckBox object at 0x0000021A43969318>
but then my len(self.il['Line2']) command does not work.
I have tried something like the following:
self.il['Line2'[i]] = QtWidgets.QCheckBox(self.il2info[i],self)
but get an error of:
IndexError: string index out of range
I have also tried to do:
self.il['Line2':[i]] = QtWidgets.QCheckBox(self.il2info[i],self)
but I am met with the following error of:
TypeError: unhashable type: 'slice'
Is there some syntax error that I am missing? Can widget objects not be stored in dictionaries? Is there a way for me to ID widgets that would allow me to store the ID in dictionary?
EDIT: My original problem has been solved as I was incorrectly defining the keys/values of my dictionary. Using a temp dictionary to collect all widgets into an array and then equating them to my master dictionary with a key of 'Line2' fixed the issue.
When you add an element as follows:
d[val1, val2] = some_value
is similar to:
d[(val1, val2)] = some_value
That is, the key is a tuple, so you must pass the tuple as a key so that it returns the value.
new_value = d[(val1, val2)]
In your case:
self.il['Line2', i] = some_value
new_value = self.il['Line2', i]
When you indicate for example:
self.il['Line2'[2]]
It is equivalent to:
self.il['n']
Or worse if you pass an index higher than the number of letters.
self.il['Line2'[6]]
Note: What you put a tuple as a key does not generate an array, if you want to get the structure of an array you must create a dictionary with dictionaries.
tmp_dict = {}
for i in range(7):
tmp_dict[i] = QtWidgets.QCheckBox(self.il2info[i],self)
self.il['Line2'] = tmp_dict
Then when you want to access you use:
#read
new_value = self.il['Line2'][i]
#write
self.il['Line2'][i] = some_value
Example:
for i in range(len(self.il['Line2'])):
new_value = self.il['Line2'][i]
self.il['Line2'][i] = some_value

Python - Add to a dictionary using a string

[Python 3.4.2]
I know this question sounds ridiculous, but I can't figure out where I'm messing up. I'm trying to add keys and values to a dictionary by using strings instead of quoted text. So instead of this,
dict['key'] = value
this:
dict[key] = value
When I run the command above, I get this error:
TypeError: 'str' object does not support item assignment
I think Python is thinking that I'm trying to create a string, not add to a dictionary. I'm guessing I'm using the wrong syntax. This is what I'm trying to do:
dict[string_for_key][string_for_value] = string_for_deeper_value
I want this^ command to do this:
dict = {string_for_key: string_for_value: string_for_deeper_value}
I'm getting this error:
TypeError: 'str' object does not support item assignment
I should probably give some more context. I'm:
creating one dictionary
creating a copy of it (because I need to edit the dictionary while iterating through it)
iterating through the first dictionary while running some queries
trying to assign a query's result as a value for each "key: value" in the dictionary.
Here's a picture to show what I mean:
key: value: query_as_new_value
-----EDIT-----
Sorry, I should have clarified: the dictionary's name is not actually 'dict'; I called it 'dict' in my question to show that it was a dictionary.
-----EDIT-----
I'll just post the whole process I'm writing in my script. The error occurs during the last command of the function. Commented out at the very bottom are some other things I've tried.
from collections import defaultdict
global query_line, pericope_p, pericope_f, pericope_e, pericope_g
def _pre_query(self, typ):
with open(self) as f:
i = 1
for line in f:
if i == query_line:
break
i += 1
target = repr(line.strip())
###skipping some code
pericope_dict_post[self][typ] = line.strip()
#^Outputs error TypeError: 'str' object does not support item assignment
return
pericope_dict_pre = {'pericope-p.txt': 'pericope_p',
'pericope-f.txt': 'pericope_f',
'pericope-e.txt': 'pericope_e',
'pericope-g.txt': 'pericope_g'}
pericope_dict_post = defaultdict(dict)
#pericope_dict_post = defaultdict(list)
#pericope_dict_post = {}
for key, value in pericope_dict_pre.items():
pericope_dict_post[key] = value
#^Works
#pericope_dict_post.update({key: value})
#^Also works
#pericope_dict_post.append(key)
#^AttributeError: 'dict' object has no attribute 'append'
#pericope_dict_post[key].append(value)
#^AttributeError: 'dict' object has no attribute 'append'
_pre_query(key, value)
-----FINAL EDIT-----
Matthias helped me figure it out, although acushner had the solution too. I was trying to make the dictionary three "levels" deep, but Python dictionaries cannot work this way. Instead, I needed to create a nested dictionary. To use an illustration, I was trying to do {key: value: value} when I needed to do {key: {key: value}}.
To apply this to my code, I need to create the [second] dictionary with all three strings at once. So instead of this:
my_dict[key] = value1
my_dict[key][value1] = value2
I need to do this:
my_dict[key][value1] = value2
Thanks a ton for all your help guys!
You could create a dictionary that expands by itself (Python 3 required).
class AutoTree(dict):
"""Dictionary with unlimited levels"""
def __missing__(self, key):
value = self[key] = type(self)()
return value
Use it like this.
data = AutoTree()
data['a']['b'] = 'foo'
print(data)
Result
{'a': {'b': 'foo'}}
Now I'm going to explain your problem with the message TypeError: 'str' object does not support item assignment.
This code will work
from collections import defaultdict
data = defaultdict(dict)
data['a']['b'] = 'c'
data['a'] doesn't exist, so the default value dict is used. Now data['a'] is a dict and this dictionary gets a new value with the key 'b' and the value 'c'.
This code won't work
from collections import defaultdict
data = defaultdict(dict)
data['a'] = 'c'
data['a']['b'] = 'c'
The value of data['a'] is defined as the string 'c'. Now you can only perform string operations with data['a']. You can't use it as a dictionary now and that's why data['a']['b'] = 'c' fails.
first, do not use dict as your variable name as it shadows the built-in of the same name.
second, all you want is a nested dictionary, no?
from collections import defaultdict
d = defaultdict(dict)
d[string_for_key][string_for_value] = 'snth'
another way, as #Matthias suggested, is to create a bottomless dictionary:
dd = lambda: defaultdict(dd)
d = dd()
d[string_for_key][string_for_value] = 'snth'
you can do something like this:
>>> my_dict = {}
>>> key = 'a' # if key is not defined before it will raise NameError
>>> my_dict[key] = [1]
>>> my_dict[key].append(2)
>>> my_dict
{'a': [1, 2]}
Note: dict is inbuilt don't use it as variable name

Categories