creating a dictionary named as variable - python

I am using pyodbc to query database and retrieve some data (obviously).
What I would like is to create new dictionaries namd according to values returned from query.
For example I have a table with 1000 items, and one of collumns in that table is a INT number which is in range 1-51.
I want to do a rundown through my table, and create dictionaries named : bought_I, sold_I, created_I, etc... where I stands for INT number.
I hope I am clear enough :)
I know I could premade those dicts, but range will not always be 1-51, and it's nicer and cleaner to do it programmatically than to hardcode it.

Don't.
Create a dictionary bought, and give it keys based on your number:
bought = {}
for number in column_x:
bought[number] = "whatever object you need here"
Same for sold, created etc.
Or just one big dict:
mydict = {"bought": {}, "sold": {}, "created": {}}
for number in column_x:
for key in mydict:
mydict[key][number] = "whatever"

Related

How to add a value to a dictionary that has a duplicate key

I have this problem where I would like to add a value to a dictionary but the key is duplicate.
I would like the key to to hold a list with multiple values
this is what I have tried
def storingPassword():
username=("bob")#key,
password=("PASSWROD1")#value
allpasswords={
"jeff":"jeff 123 ",
"bob" : "bob 123"
}
if username not in allpasswords:
allpasswords[username]=password
else:
allpasswords[username].append(password)
return allpasswords
but i keep getting this error
"AttributeError: 'str' object has no attribute 'append'"
I expect a output something like this;
"jeff":"jeff 123 ",
"bob" : ["bob 123","PASSWORD1"]
That's because the value in your allpasswords dict is a string and you are trying to treat it like a list. Why are you trying to make your data structure complex with few values as list and few as string? I recommend to convert everything to list for a simpler logic.
Hence your code should be like this:
allpasswords={
"jeff": ["jeff 123 "],
"bob" : ["bob 123"]
}
allpasswords[username].append(password)
Instead of using dict object, you can use collections.defaultdict. It will let you define a dict with default value as list. So you don't need to even explicitly initialise value of new key as list. For example:
from collections import defaultdict
my_dict = defaultdict(list)
my_dict['new_key'].append('new_value')
# dictionary will hold the value:
# {'new_key': ['new_value']})
Initiate your dictionary entry with a list instead of just a string.
allpasswords[username] = [password] # List containing a single password
You will then be able to append to it.
(Having some entries contain a string while others contain a list of strings is best avoided - when it is time to look them up or print them, you would have to check each time whether it is a list or string.)

How to Store dictionary as array object within a mongodb field

I have MongoDB collection with many documents each with fields that looks like the one shown in the picture. The problem is with the field "searched". Its values are stored as a string because of which I cannot do a query for values like this {"searched.image_hash":"some_value"}. I use python to store values into MongoDB. In python, The variable "to_search" which is stored as "searched" in mongo is in fact a dictionary. Am not sure why the dictionary in "to_search" variable is stored as string within the mongodb "searched" field. Any suggestion as how to store the dictionary as array of object in mongodb?
The code I used in python is as follows
i have many other keys going into dictionary 'di'
di['account_id'] = acc_num
di['searched']= to_search
di['breakdown_queried'] = breakdown_to_query
di['combination']= [ele for ele in to_search.keys()]
di['ad_ids'] = ad_ids
di['date'] = date.today()
lo_str= ''
di = {k: str(v) for k, v in di.items()}
mongo_obj_remote.client["dev"]["ad_stats_tracker"].delete_one({"_id": {"$in": [di['_id']]}})
di_key_li = ['_id','account_id','date', 'combination','searched', 'ad_ids','breakdown_queried']
mongo_obj_remote.insert_single_document("dev", "ad_stats_tracker", {key: di[key] for key in di_key_li})
If your data in to_search is a python dict (and not a string that looks like one), then the pymongo drivers will store the data as a BSON "object", not a string; affectively this creates a sub-document within the document being stored in the collection.
Looking at your data I would suggest that your to_search is actually a string; the format is not valid for a dict as it contains a set (which pymongo won't be able to store in mongodb anyway).
You can check it with a small amount of debug code just before you insert the data:
print(type(di['searched']))

How can I rename a dictionary within a program?

I ask the user of my program to input the number of datasets he/she wants to investigate, e.g. three datasets. Accordingly, I should then create three dictionaries (dataset_1, dataset_2, and dataset_3) to hold the values for the various parameters. Since I do not know beforehand the number of datasets the user wants to investigate, I have to create and name the dictionaries within the program.
Apparently, Python does not let me do that. I could not rename the dictionary once it has been created.
I have tried using os.rename("oldname", "newname"), but that only works if I have a file stored on my computer hard disk. I could not get it to work with an object that lives only within my program.
number_sets = input('Input the number of datasets to investigate:')
for dataset in range(number_sets):
init_dict = {}
# create dictionary name for the particular dataset
dict_name = ''.join(['dataset_', str(dataset+1)])
# change the dictionary´s name
# HOW CAN I CHANGE THE DICTIONARY´S NAME FROM "INIT_DICT"
# TO "DATASET_1", WHICH IS THE STRING RESULT FOR DICT_NAME?
I would like to have in the end
dataset_1 = {}
dataset_2 = {}
and so on.
You don't (need to). Keep a list of data sets.
datasets = []
for i in range(number_sets):
init_dict = {}
...
datasets.append(init_dict)
Then you have datasets[0], datasets[1], etc., rather than dataset_1, dataset_2, etc.
Inside the loop, init_dict is set to a brand new empty directory at the top of each iteration, without affecting the dicts added to datasets on previous iterations.
If you want to create variables like that you could use the globals
number_sets = 2
for dataset in range(number_sets):
dict_name = ''.join(['dataset_', str(dataset+1)])
globals() [dict_name] = {}
print(dataset_1)
print(dataset_2)
However this is not a good practice, and it should be avoided, if you need to keep several variables that are similar the best thing to do is to create a list.
You can use a single dict and then add all the data sets into it as a dictionary:
all_datasets = {}
for i in range(number_sets):
all_datasets['dataset'+str(i+1)] = {}
And then you can access the data by using:
all_datasets['dataset_1']
This question gets asked many times in many different variants (this is one of the more prominent ones, for example). The answer is always the same:
It is not easily possible and most of the time not a good idea to create python variable names from strings.
The more easy, approachable, safe and usable way is to just use another dictionary. One of the cool things about dictionaries: any object can become a key / value. So the possibilities are nearly endless. In your code, this can be done easily with a dict comprehension:
number_sets = int(input('Input the number of datasets to investigate:')) # also notice that you have to add int() here
data = {''.join(['dataset_', str(dataset + 1)]): {} for dataset in range(number_sets)}
print(data)
>>> 5
{'dataset_1': {}, 'dataset_2': {}, 'dataset_3': {}, 'dataset_4': {}, 'dataset_5': {}}
Afterwards, these dictionaries can be easily accessed via data[name_of_dataset]. Thats how it should be done.

Create nested python dictionary

I am using the python code below to extract some values from an excel spreadsheet and then push them to an html page for further processing. I would like to modify the code below so that I can add additional values against each task, any help
the code below does spit out the following:
{'line items': {'AMS Upgrade': '30667', 'BMS works':
'35722'}}
How can I revise the code below so that I can add 2 more values against each task i.e. AMS Upgrade and BMS works
and get the likes of (note the structure below could be wrong)
{'line items': {'AMS Upgrade': {'30667','100%', '25799'}},{'BMS works':
{'10667','10%', '3572'}} }
Code:
book = xlrd.open_workbook("Example - supporting doc.xls")
first_sheet = book.sheet_by_index(-1)
nested_dict = {}
nested_dict["line items"] = {}
for i in range(21,175):
Line_items = first_sheet.row_slice(rowx=i, start_colx=2, end_colx=8)
if str(Line_items[0].value) and str(Line_items[1].value):
if not Line_items[5].value ==0 :
nested_dict["line items"].update({str(Line_items[0].value) : str(Line_items[1].value)})
print nested_dict
print json.dumps(nested_dict)
*** as requested see excel extract below
In Python, each key of a dict can only be associated with a single value. However that single value can be a dict, list, set, etc that holds many values.
You will need to decide the type to use for the value associated with the 'AMS Upgrade' key, if you want it to hold multiple values like '30667','10%', '222'.
Note: what you have written:
{'30667','100%', '25799'}
Is a set literal in Python.

Using a python api that stores a dict in a list of dicts...with no key values

The python API (gmusicapi) stores playlists as a list of dicts with the track info as a dict inside that dict.
-edit- this is wrong. it does have some sort of key when printed, but I cant find out how to access the keys within the dict.
list = [
{ ##this dict isn't a problem, I can loop through the list and access this.
'playlistId': '0xH6NMfw94',
'name': 'my playlist!',
{'trackId': '02985fhao','album': 'pooooop'}, #this dict is a problem because it has no key name. I need it for track info
'owner': 'Bob'
},
{ ##this dict isn't a problem, I can loop through the list and access this.
'playlistId': '2xHfwucnw77',
'name': 'Workout',
'track':{'trackId': '0uiwaf','album': 'ROOOCKKK'}, #this dict would probably work
'owner': 'Bob'
}
]
I have tried using for loops and accessing it through somethings like:
def playLists(self):
print 'attempting to retrieve playlist song info.'
playListTemp = api.get_all_user_playlist_contents()
for x in range(len(playListTemp)):
tempdictionary = dict(playListTemp[x])
The problem here is tempdictionary has a dict in it called tracks but I can't seem to access the keys/value pairs inside it no matter what I do.
when printed it returns something like:
[u'kind', u'name', u'deleted', u'creationTimestamp', u'lastModifiedTimestamp', u'recentTimestamp', u'shareToken', 'tracks', u'ownerProfilePhotoUrl', u'ownerName', u'accessControlled', u'type', u'id', u'description']
where 'tracks' is a dict containing artist, title, tracknumber etc
I also tried something like:
tempdictionary['tracks'][x]['title']
with no luck. Other times I have tried creating a new dict with tracks dict as a velue but then I get an error saying it needs a value of 2 and it found something like 11 etc.
im new to python so if anyone here could help with this I would be very thankful
it does have some sort of key when printed, but I cant find out how to access the keys within the dict.
Iterate over the dict:
for key in dct:
print(key)
# or do any number of other things with key
If you'll also be looking at the values of the dict, use .items() to save yourself a dict lookup:
for key, value in dct.items():
print(key)
print(value)
You might consider using classes to encapsulate common traits. Currently, each of your track and playlist dictionaries have a lot of duplicate code (ie. "track_id=", "owner="Bob"). Using classes reduces duplicate and makes your meaning more obvious and explicit.
class AudioTrack(object):
def __init__(self, ID, album=None):
self.id = ID
self.album = album
self.owner = 'Bob'
Create a single AudioTrack objects like this:
your_first_track = AudioTrack('02985fhao', 'pooooop')
Or create a list of AudioTrack objects like this:
your_tracks = [
AudioTrack("0x1", album="Rubber Soul"),
AudioTrack("0x2", album="Kind of Blue"),
...
]
In this way, you could inspect each AudioTrack object:
your_first_track.id #Returns '02985fhao'
Or do something for all AudioTrack objects in your_tracks:
#Prints the album of every track in the list of AudioTrack intances
for track in your_tracks:
print track.album
You might make playlists using dictionaries where:
my_playlist = {
id: "0x1",
name: "my playlist",
tracks: [AudioTrack("0x1", album="Rubber Soul"),
AudioTrack("0x2", album="Kind of Blue")]
}

Categories