user771224
user771224

Reputation:

Variable names with dictionaries?

Python beginner here. A question about dictionaries.

My input is a variable length list (eg a = ['eggs', 'ham', 'bacon'...] ) which functions as a list of search terms to be used on an imported CSV file.

I have defined four functions that match each term to various values from said CSV file. So, each input term will result in four lists of results.

I would like to store the input terms as a key in a dictionary (easy enough) and the resulting four lists as values (also easy enough).

However, because the input list is of variable length I would like to set up a function to define and name the dictionaries 'term1', 'term2', illustrated very basically thus:

term1 = { 'eggs' : [[list1] , [list2] , [list3] , [list4]] }
term2 = { 'ham' : [[list1] , [list2] , [list3] , [list4]] }
term3 = { 'bacon' : [[list1] , [list2] , [list3] , [list4]] }

Is there a) a way to name dictionaries like this?; and b) AND have them be globally available? If so, how? Any and all help very much appreciated.

Upvotes: 3

Views: 16586

Answers (3)

PaulMcG
PaulMcG

Reputation: 63747

Here is how you might pre-initialize your one dictionary containing all data:

a = "eggs bacon ham".split()
summary = dict((key,([],[],[],[])) for key in a)

for lineno,line in enumerate(csv_file):
    # first element in the line is assumed to be the key ("eggs", "bacon", etc.)
    key = line[0]
    # update the data values for this key
    summary[key][0].append(lineno)
    summary[key][1].append(something_else)
    # ... etc.

I find this kind of indexed access a bit fragile though, and prefer keyed or attribute access. Your hardcoded list of 4 lists may be better represented as a dict or even objects of some simple data-tallying class.

Also, I think your "eggs", "bacon", and "ham" list will grow over time, as you find entries in your CSV file for "pancakes", "waffles", "hash browns" and so on. I have gotten to use defaultdict's more and more lately for tallying up data as I go through data files or database tables. Instead of pre-defining what keys I expect to get (and having to update the list myself when the input data gets new values added to it), defaultdict just adds new entries of the form I define:

class Tally(object):
    def __init__(self):
        self.count = 0
        self.lines = []
        self.values = []

from collections import defaultdict
summary = defaultdict(Tally)

for lineno,line in enumerate(csv_file):
    # first element in the line is assumed to be the key ("eggs", "bacon", etc.)
    key = line[0]
    # update the data values for this key
    summary[key].count += 1
    summary[key].lines.append(lineno)
    summary[key].values.append(line[1])
    # ... etc.

defaultdict saves me the cumbersome and repetitive "if key not in summarydict: add new entry..." overhead, so my code stays fairly clean.

Upvotes: 2

Cédric Julien
Cédric Julien

Reputation: 80811

You can try something like this :

results = {}
for name in ['eggs', 'ham', 'bacon']:
   results[name] = (function1(name), function2(name), function3(name), function4(name),)

where functionX are your functions that will return the listX result from CSV file or whatever.

Here you will have in the results dictionnary something like this :

results = { 
   'eggs' : (egg_list1, egg_list2, egg_list3, egg_list4), 
   'ham' : (ham_list1, ham_list2, ham_list3, ham_list4),
   'bacon' : (bacon_list1, bacon_list2, bacon_list3, bacon_list4),
}

Upvotes: 2

Martijn Pieters
Martijn Pieters

Reputation: 1123490

Not an approach I'd recommend, but you can access both the local and global namespaces as dictionaries; e.g. you can add arbitrary variables to those namespaces using the familiar dict interface:

>>> globals()['foo'] = 'bar'
>>> foo
'bar'
>>> locals()['spam'] = 'eggs'
>>> spam
'eggs'

You will run into naming conflicts though. Also, how will the rest of your code know what global variables contain your results? They'll have to do indirect look-ups too!

You better just use one dictionary containing your results, and let that be the namespace instead of the global namespace.

Upvotes: 3

Related Questions