19

I'm aware I can assign multiple variables to multiple values at once with:

(foo, bar, baz) = 1, 2, 3

And have foo = 1, bar = 2, and so on.

But how could I make the names of the variables more dynamic? Ie,

somefunction(data,tupleofnames):
    (return that each name mapped to a single datum)

somefunction((1,2,3),(foo,bar,baz))     

And have the same?

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
  • What is this act of assigning variables like this (foo, bar, baz = 1,2,3) called? (as opposed to assigning foo = 1, bar = 2, baz = 3). Thanks! – Sindhu S Jan 13 '15 at 21:09
  • 1
    Hi @sindhus! It's called 'destructuring assignment'. Python's had it for a while, and it was recently added to JavaScript. – mikemaccana Jan 13 '15 at 21:10

7 Answers7

14

There are ways to do it, but they're not nice ways, and it's considered bad practice in Python. New variables shouldn't be created by magic. If you want to have a collection of things, use a list, dictionary or set, as appropriate.

For example, you could return a dictionary: {"foo":1, "bar":2, "baz":3}

Thomas K
  • 39,200
  • 7
  • 84
  • 86
10

How about this?

def somefunction(data, tupleofnames):
    length = len(tupleofnames)
    for i in range(0, length):
        globals()[tupleofnames[i]] = data[i]

Here I assume both data and tupleofnames are lists where tupleofnames is a list of strings. But as Thomas mentioned this is not a good practice. It can easily corrupt your app.

freakish
  • 54,167
  • 9
  • 132
  • 169
  • After some deliberation: while I understand assigning what seems like arbitrary variable names can be a bad idea, I like this answer because it shows it's possible (and my interest is mainly academic). Thanks for your answer! – mikemaccana Mar 11 '11 at 19:01
6

If dictionaries are not what you want, then possibly namedtuple's are the way to go: they allow for efficient creation of several instances of data grouped together, with named attributes.

http://docs.python.org/library/collections.html#collections.namedtuple

from collections import namedtuple


mytype = namedtuple("mytype", "foo bar baz")

a = mytype(1,2,3)
a.foo
1
a.bar
2
a.baz
 3
jsbueno
  • 99,910
  • 10
  • 151
  • 209
5

You can do it like this:

    (foo, bar, baz) = (1, 2, 3)
Stefan Gruenwald
  • 2,582
  • 24
  • 30
  • 1
    and then even `(foo, bar, baz) = [None] * 3` – Tjorriemorrie Nov 12 '14 at 15:20
  • 1
    This appears to be functionally identically to the first line of code in the question, and definitely doesn't involve dynamic variable names - did you even read any part of the question body, or just the title? Or am I missing something? – Bernhard Barker May 12 '15 at 14:02
3

Check out the help docs for zip & map. e.g. for zip:-

>>>  zip( (1,2,3) , ('foo','bar','baz') )
[(1, 'foo'), (2, 'bar'), (3, 'baz')] 

map requires a function to map sequences together. But, you can use None instead of a function to return the same results as zip does, above.

>>> map( None, (1,2,3) , ('foo','bar','baz') )                                                                                       
[(1, 'foo'), (2, 'bar'), (3, 'baz')]
Alex Leach
  • 1,199
  • 2
  • 12
  • 26
-1
(foo, bar, baz) = [None] * 3    
a,b,c = [0]*3    
a,b,c = ["nihao"]*3
user5249203
  • 4,436
  • 1
  • 19
  • 45
gaozhidf
  • 2,621
  • 1
  • 22
  • 17
-1

I understand the answers above are already all they need, but I have a nice cool programming trick that could also help you when you want to assign a particular tuple to variables.

tuple T

T = (A,B,C)

the variables

var1, var2, var3 = T

Community
  • 1
  • 1