Store Widgets in Dictionary - python

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

Related

Assigning values to variables using for loop

I want to create variables that hold the values packet.{name of the variable}.
For example, I want sectID to get the value of packet.sectID.
I've tried:
lst = ['sectID','MP_Sector_ID']
for field in lst:
globals()[field]=packet.field
but packet.field doesn't give me the right value.
Also packet is a class.
lst = ['sectID','MP_Sector_ID']
for field in lst_duplicates:
globals()[field] = getattr(packet, field)

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)

How to change specific value of a dictionary with multiple values (tuple) without getting TypeError

I have a function below which searches for a dictionary key match using an inputted function parameter. If a key match is found I want the value at index 1 (the team) to change to the desired team inputted when the function is called:
dict1 = {'Messi' : ('Argentina','Barcelona'), 'Ronaldo' : ('Portugal','Juventus'), 'Robben': ('Netherlands','Bayern')}
def setNewTeam(plyr, newTeam):
for x in dict1:
if plyr == x:
dict1[plyr][1] = newTeam
setNewTeam('Messi', 'Manchester')
When I run this code however, I get:
TypeError: 'tuple' object does not support item assignment
I know this must be because tuples are not mutable but there must be a way of making this work since i'm working with dictionaries, can anyone lend a hand here?
Thank you!
As the error message says, you cannot assign new items to tuples because tuples are immutable objects in python.
my_tup = (1,2,3)
my_tup[0] = 2 # TypeError
What you could do is using a list instead:
dict1 = {'Messi' : ['Argentina','Barcelona'], 'Ronaldo' : ['Portugal','Juventus'], 'Robben': ['Netherlands','Bayern']}
def setNewTeam(plyr, newTeam):
for x in dict1:
if plyr == x:
dict1[plyr][1] = newTeam
setNewTeam('Messi', 'Manchester')
Note how lists are created using [] while tuples use ().
dict1 = {'Messi' : ('Argentina','Barcelona'), 'Ronaldo' : ('Portugal','Juventus'), 'Robben': ('Netherlands','Bayern')}
def setNewTeam(plyr, newTeam):
for x in dict1:
if plyr == x:
dict1[plyr] = (dict1[plyr][0], newTeam)
setNewTeam('Messi', 'Manchester')
Since you want to update values, tuple is not the good data-structure. You should use a list.
If you still want to use a tuple, you can build a brand new tuple with :
dict1[plyr] = (dict1[plyr][0], newTeam)
dict1[plyr][1] = newTeam
Tuples are immutable, but lists are not. You can do something like:
list1 = list(dict1[plyr])
list1[1] = newTeam
dict1[plyr] = tuple(list1)
It will add the newTeam to your desired location, and it will still be a tuple.

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

Add dictionary as value of dictionary in 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())

Categories