To declare multiple variables at the "same time" I would do:
a, b = True, False
But if I had to declare much more variables, it turns less and less elegant:
a, b, c, d, e, f, g, h, i, j = True, True, True, True, True, False, True ,True , True, True
Is there a better / elegant / convenient way to do this?
Thanks in advance!
Edit:
This must be very basic, but if I do used a list or a tuple for storing the variables, how would I have to approach so that I would be helpful since:
aList = [a,b]
Is not valid, I would have to do:
a, b = True, True
Or what am I missing?
Use a list/dictionary or define your own class to encapsulate the stuff you're defining, but if you need all those variables you can do:
As others have suggested, it's unlikely that using 10 different local variables with Boolean values is the best way to write your routine (especially if they really have one-letter names :)
Depending on what you're doing, it may make sense to use a dictionary instead. For example, if you want to set up Boolean preset values for a set of one-letter flags, you could do this:
If you prefer, you can also do it with a single assignment statement:
The second parameter to
dict
isn't entirely designed for this: it's really meant to allow you to override individual elements of the dictionary using keyword arguments liked=False
. The code above blows up the result of the expression following**
into a set of keyword arguments which are passed to the called function. This is certainly a reliable way to create dictionaries, and people seem to be at least accepting of this idiom, but I suspect that some may consider it Unpythonic.</disclaimer>
Yet another approach, which is likely the most intuitive if you will be using this pattern frequently, is to define your data as a list of flag values (
True
,False
) mapped to flag names (single-character strings). You then transform this data definition into an inverted dictionary which maps flag names to flag values. This can be done quite succinctly with a nested list comprehension, but here's a very readable implementation:The function
invert_dict
is a generator function. It generates, or yields — meaning that it repeatedly returns values of — key-value pairs. Those key-value pairs are the inverse of the contents of the two elements of the initialflags
dictionary. They are fed into thedict
constructor. In this case thedict
constructor works differently from above because it's being fed an iterator rather than a dictionary as its argument.Drawing on @Chris Lutz's comment: If you will really be using this for single-character values, you can actually do
This works because Python strings are iterable, meaning that they can be moved through value by value. In the case of a string, the values are the individual characters in the string. So when they are being interpreted as iterables, as in this case where they are being used in a for loop,
['a', 'b', 'c']
and'abc'
are effectively equivalent. Another example would be when they are being passed to a function that takes an iterable, liketuple
.I personally wouldn't do this because it doesn't read intuitively: when I see a string, I expect it to be used as a single value rather than as a list. So I look at the first line and think "Okay, so there's a True flag and a False flag." So although it's a possibility, I don't think it's the way to go. On the upside, it may help to explain the concepts of iterables and iterators more clearly.
Defining the function
invert_dict
such that it actually returns a dictionary is not a bad idea either; I mostly just didn't do that because it doesn't really help to explain how the routine works.Apparently Python 2.7 has dictionary comprehensions, which would make for an extremely concise way to implement that function. This is left as an exercise to the reader, since I don't have Python 2.7 installed :)
You can also combine some functions from the ever-versatile itertools module. As they say, There's More Than One Way To Do It. Wait, the Python people don't say that. Well, it's true anyway in some cases. I would guess that Guido hath given unto us dictionary comprehensions so that there would be One Obvious Way to do this.
Sounds like you're approaching your problem the wrong way to me.
Rewrite your code to use a tuple or write a class to store all of the data.
This is an elaboration on @Jeff M's and my comments.
When you do this:
It works with tuple packing and unpacking. You can separate the packing and unpacking steps:
The first line creates a tuple called
_
which has two elements, the first with the value ofc
and the second with the value ofd
. The second line unpacks the_
tuple into the variablesa
andb
. This breaks down your one huge line:Into two smaller lines:
It will give you the exact same result as the first line (including the same exception if you add values or variables to one part but forget to update the other). However, in this specific case, yan's answer is perhaps the best.
If you have a list of values, you can still unpack them. You just have to convert it to a tuple first. For example, the following will assign a value between 0 and 9 to each of
a
throughj
, respectively:EDIT: Neat trick to assign all of them as true except element 5 (variable
f
):I like the top voted answer; however, it has problems with list as shown.
This is discussed in great details (here), but the gist is that
a
andb
are the same object witha is b
returningTrue
(same forid(a) == id(b)
). Therefore if you change an index, you are changing the index of botha
andb
, since they are linked. To solve this you can do (source)This can then be used as a variant of the top answer, which has the "desired" intuitive results