2

This is probably something very basic and simple, and I'm probably just googling for the wrong terms, but hopefully someone here can help me. (I'm still a beginner to programming, which is probably obvious from this question.)

I'm looking for a way to access variables from strings.

Like this:

A1 = {}
B1 = {}
C1 = {}

mylist = ["A","B","C"]

for blurb in mylist:
    blurb1.foo()

Right now I'm using if/elif-constructions in such cases:

if blurb == "A":
    A1.foo()
elif blurb == "B":
    B1.foo()
elif blurb == "C":
    C1.foo()

That works, but surely there's a more elegant way of doing it?

Thanks for any help! Lastalda


Edit2: trying to clarify again (sorry for not being very coherent before, it's hard for me to get this across):

I would like to create and access objects from strings.

So if i have a function that returns a string, I want to create e.g. a list using this string as the list name, and then do stuff with that list.

x = foo() # foo returns a string, e.g. "A"
# create list named whatever the value of x is
# in this case: 
A = []

Isn't there anything more elegant than preparing lists for all possible outcomes of x and using long elif constructions or dictionaries? Do I have to use eval() in that case? (I'm hesitant to use eval(), as it's considered dangerous.)

I hope it's finally clear now. Any help still appreciated!

CodingCat
  • 4,999
  • 10
  • 37
  • 59
  • are you looking for the switch statement? – victorsavu3 Aug 08 '12 at 12:54
  • no he is looking for a way to run functions/or access variables (like his dicts above) via string conversion (or other types of conversion) – Inbar Rose Aug 08 '12 at 13:04
  • something like that, yes. How would i do that? – CodingCat Aug 09 '12 at 13:00
  • I've updated my answer to try to answer your revised request, but could you provide a use case _why_ you want to do this. – Foon Aug 11 '12 at 01:52
  • @Lastalda could you mark an answer as accepted, or could you inform us if you need more help? – Inbar Rose Aug 14 '12 at 14:20
  • @Inbar none of the answers so far really answered my question yet. All of them raise important points, but they're not really answering my question. That's why I haven't accepted any yet. – CodingCat Aug 29 '12 at 07:23
  • @Lastalda why dont you edit your question with a desired result? what do you want the solution to be? how do you want it to look? – Inbar Rose Sep 02 '12 at 08:00
  • @Inbar: I tried that before but got no answers afterwards anymore. :( But I've tried it again, hopefully the question's clear now? – CodingCat Sep 07 '12 at 09:08
  • @Lastalda sorry, but you are simply not clear on what you are trying to do. instead of trying to explain the specific function you want - maybe you can inform us as to what it is you are trying to accomplish on a larger scale, maybe your approach can be improved, maybe a different method than the one you are having trouble explaining should be used. – Inbar Rose Sep 09 '12 at 08:56

4 Answers4

11

I think you want something like

lookup = {"A": A1, "B": B1, "C": C1}
obj = lookup.get(blurb,None)
if obj:
   obj.foo()

This is usually suggested when someone wants to do something with a switch statement (from c/java/etc.) Note that the lookup.get (instead of just lookup[blurb] handles the case where blurb is something other than one of the values you defined it for... you could also wrap that in a try/except block.


Updated answer based on your revised question, which builds on what Joachim Pileborg had said in another answer.

There are probably better/cleaner ways to do this, but if you really want to set/get via strings to manipulate global objects, you can do that. One way would be: To create a new object named "myvariable" (or to set "myvariable" to a new value)

joe = "myvariable"
globals().update([[joe,"myvalue"]])

To get the object "myvariable" is assigned to:

globals().get(joe,None) 

(or as mentioned in another answer, you could use try/except with direct hash instead of using get)

So for later example, you could do something like:

for myobject in mylist:
    # add myobject to list called locus
    # e.g. if locus == "A", add to list "A", if locus == "B" add to list B etc.
    obj = globals().get(myobject.locus,None) # get this list object
    if not obj: # if it doesn't exist, create an empty list named myobject.locus
        obj = []
        globals().update([[myobject.locus,obj]]
    obj.append(myobject) #append my object to list called locus
Foon
  • 6,148
  • 11
  • 40
  • 42
  • this is messy, adds a lot of extra checks and a whole extra dictionary.... not very effective for lots of data, or different types of required functions... better use `eval()`. – Inbar Rose Aug 08 '12 at 13:11
  • eval is evil! (most of the time) – Matthias Aug 08 '12 at 13:14
  • 2
    "A whole extra dictionary." Oh no, one whole dictionary! LOL! – kindall Aug 08 '12 at 13:16
  • @Foon: This works, thanks, though it was not exactly what I was looking for. Is there no way to create variable names from strings, like from the output of a function? – CodingCat Aug 10 '12 at 12:42
7

You could get the module object, and use getattr to get variables/functions from a string:

import sys

A = {}
B = {}
C = {}

modname = globals()['__name__']
modobj  = sys.modules[modname]

mylist = ["A","B","C"]

for name in mylist:
    print '%s : %r' % (name, getattr(modobj, name))

The above program will print:

A : {}
B : {}
C : {}

However, it has nothing to do with "wildcards" that you reference in your question, but you don't show any searching for "wildcards".

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

use eval().

example:

A1 = []
B1 = []
C1 = []

mylist = ["A","B","C"]

for blurb in mylist:
    eval("%s1.append(blurb)" % blurb)

print A1,B1,C1
>>> 
['A'] ['B'] ['C']

and for your code it can be:

for blurb in mylist:
    eval("%s1.foo()" % blurb)
Inbar Rose
  • 41,843
  • 24
  • 85
  • 131
1

I looks like you simply want a dictionary and to look it up rather than run a bunch of checks.

dict_look_up = {'A' : A1, 'B' : B1, 'C' : C1}
try:
    dict_look_up[blurb].foo()
except KeyError:
    #whatever on item not found

try/except blocks are incredibly important in Python (better to ask for forgiveness than permission), so if you're learning I recommend using them from the get go.

DrGodCarl
  • 1,666
  • 1
  • 12
  • 17