0

I'm having an absolute mind-block. This is my data:

db_one = 1
db_two = 2
db_three = 3
db_four = 4
list_to_iterate = ['one','two','three','four']

for each_item in list_to_iterate:
    new_string = 'db_' + each_item
    print(new_string)

I want to loop through each item in list_to_iterate, prefix the item with 'db_'; and then return the object to which that string refers, so e.g. 'one' in the list -> is converted to 'db_one' -> prints out 1.

Can someone help?

desertnaut
  • 57,590
  • 26
  • 140
  • 166
Slowat_Kela
  • 1,377
  • 2
  • 22
  • 60

4 Answers4

1

If you are trying to iterate over a collection of objects, it's imperative that you separate the name from the object. This is a pretty common pitfall, we give values names (which we call variables) and so the assumption is made that this is the only way to access them.

However, it's best to ignore the names in this case. If you have a bunch of objects that you need access to, just put those objects in a container: list, set, tuple, dict, etc.

If the name matters to you more than order, then a dict might be the way to go:

db1, db2, db3 = 1, 2, 3

db_dict = {'db1': db1, 'db2': db2, 'db3': db3}

for name, obj in db_dict.items():
    print(name, obj)

db1 1
db2 2
db3 3

Otherwise, what happens if you add a new name (variable)? Say I want db4 now. Well, I need to go in and make a code change. This becomes very fragile and difficult to extend. While you could use exec or globals() or locals(), this is generally regarded as an anti-pattern because you don't really need the names, you need the values themselves, and a consistent way to access them.

C.Nivs
  • 12,353
  • 2
  • 19
  • 44
1

Replace the 4 like-named variables with a dict, and the problem goes away.

db = {
  'one': 1,
  'two': 2,
  'three': 3,
  'four': 4
}

list_to_iterate = ['one','two','three','four']

for each_item in list_to_iterate:
    new_string = db[each_item]
    print(new_string)
chepner
  • 497,756
  • 71
  • 530
  • 681
0

To answer your question: You can use locals() if you really need to, like this:

for item in list_to_iterate:
   key = "db_" + item
   print(locals()[key])

But it really sounds as if you need to use a different pattern (maybe dictionary):

objects = {"db_one": 1, "db_two": 2, "db_three": 3, "db_four": 4}
items = ["one", "two", "three", "four"]
for item in items:
    key = "db_" + item
    print(objects[key])
Slobodan Ilic
  • 789
  • 8
  • 8
-2

You can do that with eval or exec, as mentioned it is discouraged

db_one = 1
db_two = 2
db_three = 3
db_four = 4
list_to_iterate = ['one','two','three','four']

for each_item in list_to_iterate:
    new_string = 'db_' + each_item
    exec("print(%s)"%new_string)

To convert string to variable name

B. Diarra
  • 25
  • 3