37

if I have a list, say:

ll = ['xx','yy','zz']

and I want to assign each element of this list to a separate variable:

var1 = xx
var2 = yy
var3 = zz

without knowing how long the list is, how would I do this? I have tried:

max = len(ll)
count = 0
for ii in ll:
    varcount = ii
    count += 1
    if count == max:
        break

I know that varcount is not a valid way to create a dynamic variable, but what I'm trying to do is create var0, var1, var2, var3 etc based on what the count is.

Edit::

Never mind, I should start a new question.

martineau
  • 119,623
  • 25
  • 170
  • 301
David Yang
  • 2,101
  • 13
  • 28
  • 46
  • 25
    why on earth would you want to do that? – Rohit Jain Oct 10 '13 at 15:34
  • 3
    Variables are just names. What is wrong with `ll[0], ll[1], ll[2] ...` etc? – dansalmo Oct 10 '13 at 15:35
  • What is the usecase ? Looks like what could rethink your approach – karthikr Oct 10 '13 at 15:35
  • Why would you want to move something to another container when you can just access it from the container that it's already in? – Drew Oct 10 '13 at 15:36
  • I'm making API calls and I need to parse a csv file to extract the data I'm inputting into my API calls. – David Yang Oct 10 '13 at 15:38
  • What's wrong with using the csv module? – Tyler Eaves Oct 10 '13 at 15:39
  • 2
    Please see [Keep data out of your variable names](http://nedbatchelder.com/blog/201112/keep_data_out_of_your_variable_names.html) – David Robinson Oct 10 '13 at 15:40
  • 1
    If you don't know how long the list is, how would you expect to name all the variables? – twalberg Oct 10 '13 at 15:50
  • I have just started learning Python and i'm also facing a _similar_ (i have fixed set of entries) situation. I have a config file which I will be grepping for a string and if a row matches, i would like to read that row. Now each row has a fixed set (six) of entries comprising of string and integer (port #), all separated by a delimiter. To make my script more readable, i would like to assign each entry a name so they are easily identifiable when i'm working or for the maintainer. Just wanted to know whether this is a valid use-case or good practice to have variable assigned to each entry? – Technext Sep 08 '18 at 14:43
  • @rohit-jain for situations where you need to identify and isolate data from tuples and place them into variables so the tuple data can be used elsewhere in the code. – user3553260 Jun 07 '19 at 06:31
  • @twalberg, maybe its a bit late, but you have to go with range, so you have variable[temporary variable] – y.y Apr 27 '21 at 09:03

7 Answers7

65

Generally speaking, it is not recommended to use that kind of programming for a large number of list elements / variables.

However, the following statement works fine and as expected

a,b,c = [1,2,3]

This is called "destructuring" or "unpacking".

It could save you some lines of code in some cases, e.g. I have a,b,c as integers and want their string values as sa,sb,sc:

sa, sb,sc = [str(e) for e in [a,b,c]]

or, even better

sa, sb,sc = map(str, (a,b,c) )
cmantas
  • 1,516
  • 14
  • 14
  • Thanks for this answer, this is what I came here looking for. Didn't have an interpreter in front of me, and wanted to know if `problem, solution = "1+1=2".split("=")` was valid, given that `split()` returns an array rather than 2 values – JHixson Dec 06 '16 at 19:45
  • Not sure what you mean. If None is part of the "result" statement, eg `a,b = None, 1`, then it will be assigned to the according variable (in this case `a`). – cmantas Jun 28 '18 at 06:43
  • 2
    This is a great feature of python (aka "tuple unpacking"), and it is often useful in cases like the `problem, solution = ...` situation described by @JHixson... But it does not match the OP's stated condition of _not knowing how long the list is._ – alexis Dec 01 '20 at 12:34
31

Not a good idea to do this; what will you do with the variables after you define them?

But supposing you have a good reason, here's how to do it in python:

for n, val in enumerate(ll):
    globals()["var%d"%n] = val

print var2  # etc.

Here, globals() is the local namespace presented as a dictionary. Numbering starts at zero, like the array indexes, but you can tell enumerate() to start from 1 instead.

But again: It's unlikely that this is actually useful to you.

alexis
  • 48,685
  • 16
  • 101
  • 161
12

You should go back and rethink why you "need" dynamic variables. Chances are, you can create the same functionality with looping through the list, or slicing it into chunks.

Darrick Herwehe
  • 3,553
  • 1
  • 21
  • 30
  • 5
    +1 - Sometimes, the best answer is to not answer but instead to say "this isn't good". –  Oct 10 '13 at 15:38
  • You may be right. I guess lists was a simplification. What I'm really dealing with is a Dataframe of unknown length that I have to parse into a format that is compatible with API calls. Which means I'm basically creating a dictionary for every "line" of the dataframe. In that case, I'll have to create the same number of distinct dictionaries anyway, so I thought I'd just create variables instead. I'll keep thinking about it – David Yang Oct 10 '13 at 15:44
  • `that is compatible with API calls`, its seems a XY problem. You should state the actual problem, rather than how you are assuming you need to solve it – Abhijit Oct 10 '13 at 15:48
  • Sounds like you should start a new question, asking for advice on how to solve the problem in a different way instead of ways to make your solution work. – Darrick Herwehe Oct 10 '13 at 15:50
3

If the number of Items doesn't change you can convert the list to a string and split it to variables.

wedges = ["Panther", "Ali", 0, 360]
a,b,c,d = str(wedges).split()
print a,b,c,d
user1767754
  • 23,311
  • 18
  • 141
  • 164
  • this actually works for what I need - converting an array to individual args in a function parameter list – WestCoastProjects Nov 14 '17 at 01:45
  • Creating a string from the list just to split it up again makes no sense at all. This will lose type information, add extra punctuation to the results, and possibly fail when one of the lists is... anything remotely interesting. A nested list or tuple, a multi-word string... – Karl Knechtel Oct 19 '22 at 20:23
1

Instead, do this:

>>> var = ['xx','yy','zz']
>>> var[0]
'xx'
>>> var[1]
'yy'
>>> var[2]
'zz'
dansalmo
  • 11,506
  • 5
  • 58
  • 53
-1

I have found a decent application for it. I have a bunch of csv files which I want to save as a dataframe under their name:

all_files = glob.glob(path + "/*.csv")
name_list = []
for f in all_files:
    name_list.append(f[9:-4])
for i,n in enumerate(name_list):
    globals()[n] = pd.read_csv(all_files[i])
-1

This should do it (though using exec is not recommended):

for num in range(len(your_list)):
    exec('var'+str(num)+' = your_list[num]')
  • **Do not ever use `exec` on data that could ever possibly come, in whole or in part, directly or indirectly, from outside the program. It is a critical security risk that enables the author of that data to run arbitrary code. It cannot reasonably be sandboxed (i.e. without defeating the purpose).** – Karl Knechtel Oct 19 '22 at 20:25