0

Can someone explain to me, how to print the content of the following variables in a loop?

Week23 = [12-9, "free", 15.30-12.30, "free", 12-9]
Week24 = []
Week25 = []
Week26 = []
Week27 = []
Week28 = []
Week29 = []
...

I have tried playing around with the following, but it is not printing the content. The exec statement merely prints out "Week23" etc. The eval statement doesn't work due to a parsing error.

import numpy as np
length = np.linspace(23,42,42-23+1)

for i in length:
    print("Week" + str(i))
    # print(eval("Week" + str(i)))
    # exec('print("Week" + str(i))')
bgaard
  • 132
  • 3
  • 13
  • 1
    Why do you have separately named lists like that ? You should make them members of a list or a dict. [Keep data out of your variable names](https://nedbatchelder.com/blog/201112/keep_data_out_of_your_variable_names.html) – PM 2Ring Oct 16 '17 at 10:07
  • 1
    Have you considered have your variables into an Array? Something like ar = [Week23, Week24, Week25,...] an then print individually: for vr in ar: print(vr) – Raúl Reguillo Carmona Oct 16 '17 at 10:07
  • 1
    I answered how this could be achieved but you should consider a better storage such as a `list` or a `dict` if you dont need them starting with `0` and being incremental. – Adirio Oct 16 '17 at 10:09
  • Yeah, I considered a dict as well, but it's the same problem. How do I turn each variable into a segment of a dict without having to enter all the variable names manually? This is a very simplified example. I need to do it for a very large amount of data that is all written on the stated form. – bgaard Oct 16 '17 at 10:10
  • 1
    BTW, `eval` and `exec` should generally be avoided because they can be a security risk. Here's some more pertinent info from Ned Batchelder: [Eval really is dangerous](http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html). – PM 2Ring Oct 16 '17 at 10:15
  • 1
    The answer that you've accepted that uses `locals()` will only work in the global namespace (where `locals()` returns the `globals()` dict), it will fail inside a function. You _could_ do it using the `globals()` dict, but you **really** shouldn't manhandle `locals()` or `globals()` like this! Use your own dictionary. – PM 2Ring Oct 16 '17 at 10:21
  • 1
    Trust me, you _really_ don't want to create variables dynamically like that. For further info on this important topic please see [How do I create a variable number of variables?](https://stackoverflow.com/questions/1373164/how-do-i-create-a-variable-number-of-variables) and [Why you don't want to dynamically create variables](http://stupidpythonideas.blogspot.com.au/2013/05/why-you-dont-want-to-dynamically-create.html). – PM 2Ring Oct 16 '17 at 10:28
  • 1
    Why is your accepted solution better than using a dict with dynamicallly generated keys? `alldat['Week{}'.format(i)]` and now there's no abomination in your code. You probably will need `eval`/`globals` _once_ if you want to change to a sane data model. But then bury this knowledge and use a dict/list. – Andras Deak -- Слава Україні Oct 16 '17 at 10:53
  • The data I'm working with IS on the form described in the problem - I would not write it this way myself. And there is a lot of it. The accepted answer is adequate for my situation, and is hence a solution for this case. Thanks for all the replies. It was very helpful. – bgaard Oct 16 '17 at 14:15

4 Answers4

-1

You can use global() to get a dictionary of global variables and subset it using your logic with the addition of converting i to integer before converting it to string:

for i in length:
    print(globals()["Week" + str(int(i))])
clemens
  • 6,653
  • 2
  • 19
  • 31
-2

You can use locals() function:

Week23 = [12-9, "free", 15.30-12.30, "free", 12-9]
Week24 = []


for week in [23,24]:
    print (locals()['Week%s' % week])

More pythonic would be a dictionary.

Maurice Meyer
  • 17,279
  • 4
  • 30
  • 47
  • I ended up turning it into a list, since I have to work with the data later. `for i in length: Weeks.append(locals()['Week%s' % int(i)]) ` – bgaard Oct 16 '17 at 10:22
-2

The problem is in the array length. numpy.linspace() actually generates an array of float as below.

[23.0, 24.0, ..., 42.0]

Try these codes, you should get what you want.

for i in range(23, 43):
    print("Week" + str(i))
    print(eval("Week" + str(i)))

At last, using a variable as part of the name is really not a good idea. Try dict if you can.

George Lei
  • 467
  • 5
  • 5
-3

When I try to run your code as it is, I get the following:

Week23.0
Week24.0
Week25.0
Week26.0
Week27.0
Week28.0
Week29.0
Week30.0
Week31.0
Week32.0
Week33.0
Week34.0
Week35.0
Week36.0
Week37.0
Week38.0
Week39.0
Week40.0
Week41.0
Week42.0

So I only see problem with floats, since you used linspace, try range, and try not to escape variable name inside exec'ed string:

for i in range(23, 42+1):
    print("Week" + str(i))
    print(eval("Week" + str(i)))
    exec('print(Week' + str(i) + ')')

if you insist on linspace, try and convert it to integer before using. Also, some reusability

import numpy as np
length = np.linspace(23, 42, 42-23+1)

for i in length:
    var_name = "Week%i" % i
    print(var_name)
    print(eval(var_name))
    exec('print(%s)' % var_name)
E P
  • 116
  • 8