-3

I am using Python 2.5. In the code below want to print either err1, err2 or err3 depending on the value of x. Is it possible to create the variables err1, err2 or err3 by joining "err" plus the value of x?

err1 = 'error foo1'
err2 = 'error foo2'
err3 = 'error foo3'

x = 1

print err + x
bob_the_bob
  • 345
  • 1
  • 13

6 Answers6

3

You'd be better off re-writting it to use a dictionary if you want variable variable names.

err = {
    '1': 'This is Err1',
    '2': 'This is Err2',
    '3': 'This is Err3',
}

print err[str(x)]
Rejected
  • 4,445
  • 2
  • 25
  • 42
  • 5
    Why use `str` to create dictionary keys? Can't they be ints too? – Sam Mussmann Apr 22 '14 at 18:26
  • @SamMussmann They can be anything hashable. I used strings in this instance because I have no idea how else he's going to be getting/generating these keys, and thus far he's using string concatenation. If he's looking at adding 1 to err to make err1, he may be looking to adding 1 to that to make err11. – Rejected Apr 22 '14 at 18:31
2

While what you want to do is possible, it's not recommended. Instead, use a dictionary:

err={}
err[1] = 'error foo1'
err[2] = 'error foo2'
err[3] = 'error foo3'

print err[x]

While dynamically creating and referencing variables on the fly are an interesting aspect of many scripting languages, there are almost always to accomplish the same thing in a more straight-forward manner.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • I'm not sure I fully understand your answer. You can easily convert a integer to a string in any non-scripting language. And why is repeating `'error foo'` thrice better than concatenating? – loopbackbee Apr 22 '14 at 18:28
  • The question isn't "how do I print a string followed by a number", the question was about how to dynamically reference a variable. It's not better to repeat "error foo" three times, but that's not what I think is being asked. – Bryan Oakley Apr 22 '14 at 18:31
1

It is not really recommended, but you want:

x = 1
print getattr(__import__(__name__), 'err' + str(x))
# 'error foo1'
njzk2
  • 38,969
  • 7
  • 69
  • 107
0

Yes. Using str():

print 'err' + str(x)

But as pointed by others in the comments, constructing a variable name on the fly by concatenating strings is not a good way to do things. Instead define a dictionary like:

error_codes = {}
error_codes[1] = 'error foo1'
error_codes[2] = 'error foo2'
error_codes[3] = 'error foo3'

Now based on value of x do:

print error_codes[x]
shaktimaan
  • 11,962
  • 2
  • 29
  • 33
  • 1
    This isn't exactly what they are asking. They aren't asking how to join strings, but rather how to reference variables in a dynamic fashion. – Bryan Oakley Apr 22 '14 at 18:24
  • Also, the use of `str()` in `str('err')` has nothing to do with `err` (without quotes) not being defined, it's completely unecessary. If `err` wasn't defined, and you'd use `str(err)`, you'd still get a `NameError`. – Lukas Graf Apr 22 '14 at 18:27
  • @LukasGraf I use `str('err')` and not `str(err)`. Could you please read my answer in its entirety? – shaktimaan Apr 22 '14 at 18:30
  • Yes. And it makes no sense (it's a no-op), and the justification you give for it is incorrect and misleading: It's entirely unrelated to a local variable named `err`. – Lukas Graf Apr 22 '14 at 18:33
  • @LukasGraf I mixed up a few things. Agreed. Thanks. – shaktimaan Apr 22 '14 at 18:35
0

If you absolutely have to, you could use locals() to access local variables by a dynamic name (or globals() for that matter).

For example:

foo0 = 'a'
foo1 = 'b'
foo2 = 'c'

for i in range(3):
    name = 'foo%s' % i
    value = locals().get(name)
    print value

However, for locals() this should be considered read only use. Modifying values in locals() may seem to work in the interactive interpreter, but is unreliable. (Modifying values in globals() is reliable as far as I know, but I'd strongly advise doing that in production code.)

If the dynamic names you want to use are attributes on objects however, you can use getattr(obj, name) and setattr(obj, name, value), which are equivalent to value = obj.foo and obj.foo = value respectively. Those are "safe" and would work reliably. However, because it makes code very hard to read and understand without running it, they should be used sparingly for this purpose.

Lukas Graf
  • 30,317
  • 8
  • 77
  • 92
-3

I suppose that you want to simply display the string along with the integer value. So simply try using format specifiers for printing/displaying purpose:

For eg in your case: print 'err%d'%x

ρss
  • 5,115
  • 8
  • 43
  • 73
  • No, this will print "error 1". They don't want that. They want the equivalent of doing `print err1` – Bryan Oakley Apr 22 '14 at 18:28
  • Edited the answer for exact output – ρss Apr 22 '14 at 18:30
  • You still aren't answering the question that was asked. Ignore what's in the variables. Assume you have three variables named `err1`, `err2` and `err3` and you have no idea what's in them. Given the number `1`, how do you reference `err1`? _that's_ the question being asked IMO. – Bryan Oakley Apr 22 '14 at 18:34
  • You are right and I am left. I misunderstood the question. :) – ρss Apr 22 '14 at 18:40