To assign values to multiple variables it is only to follow this structure: a, b, c = 1, 2, 3; This I know, but what if for example I want to store multiple values that came from an input without knowing the amount of values? How do I do that?
To assign values to multiple variables it is only to follow this structure: a, b, c = 1, 2, 3; This I know, but what if for example I want to store multiple values that came from an input without knowing the amount of values? How do I do that?
In general, if you do not have exactly one value for each variable, that is, if the variables will have the same functionality and save elements of a sequence, then it is best to do this: General, a list.
So let's suppose you make an input, go with a split, and then having a sequence with no known length at the time of programming, you want to assign it to a variable: you do not have to do anything else, because the content already is a list - and the list is already the value returned by the split value. I'll follow with examples at the interactive prompt (the prompt has In[XX]
instead of the traditional >>>
because it's an iPython shell - the language used is exactly the same as the normal shell's Python):
In [83]: entrada = input("Entre com valores separados por espaço: ").split()
Entre com valores separados por espaço: teste de entrada de várias palavras
In [84]: print(entrada)
['teste', 'de', 'entrada', 'de', 'várias', 'palavras']
So, like I said, if each value you typed is going to be used in the same way, then the simpler is I keep the variable entrada
. A for
will process word for word from this list, much simpler than if you were each word in a different variable - just do for palavra in entrada:
.
*
as prefix to indicate that in that variable goes a list with "all that is left". Continuing the previous example:
In [91]: a, b, *c = entrada
In [92]: print (f"a: {a}, b: {b}, c: {c}")
a: teste, b: de, c: ['entrada', 'de', 'várias', 'palavras']
Note that *
does not have to be used in the last variable - if the ones I want to separate are the first and last words, for example, and I want to keep all the others in a list,
In [93]: a, *b, c = entrada
In [94]: print (f"a: {a}, b: {b}, c: {c}")
a: teste, b: ['de', 'entrada', 'de', 'várias'], c: palavras
If there is a maximum number of items in your entry, but it can optionally be smaller, you can do it: we create an iterator that fills in the missing items with a "blank" value as None
. There are several ways to do this - and we can use a list comprehension with a% ternary% for our purposes. Important to realize here, is that the caveats for creating the dynamic variables are already beginning to apply, and the code begins to be complex, especially for those who do not know the language well:
In [101]: a, b, c, d, e, f, g, h = [entrada[i] if i < len(entrada) else None for i in range(8)]
In [102]: print(a, b, c, d, e, f, g, h)
teste de entrada de várias palavras None None
So far this is part of the normal syntax of Python, just a more advanced aspects of it. Specifically what you want can be done in another way - using Python's introspection and dynamism capabilities, which allow the dynamic change of variables by the program being executed.
This is not hard to do - but for the reason I mentioned earlier in this answer, it does not make sense - since if you are going to dynamically create a variable, you will not be able to write any code that uses this variable by name more ahead, since it does not know if it will exist. So it makes more sense to keep the sequence as a list, or even put the sequence in a dictionary if appropriate.
But for purposes of example, what you can use in this case is the fact that calling the if
function of Python returns a dictionary with the global variables of the current module. If we use it as a common dictionary, the entries created in this dictionary are created "real" as global variables. This is possible because when manipulating the dictionary, variable names are strings - and strings are data that we can manipulate with the various Python functions. Only - I insist - this would not have been used in a normal program.
The following section creates the variables, starting with globals()
and incrementing the digit for each word in the sequence:
In [97]: for i, palavra in enumerate(entrada):
...: globals()['a' + str(i)] = palavra
...:
...:
In [98]: print(a0, a1, a2, a3, a4)
teste de entrada de várias
In [99]: print(a5)
palavras
In [100]: print(a6)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-100-ff75f4805c17> in <module>
----> 1 print(a6)
NameError: name 'a6' is not defined
I let the error pop up on purpose - if it was a program, not an example in interactive mode, the code behind the creation of the variables would not know which of those variables a0
would have been created - the only way to use some would be putting its usage within a aN
- which overlaps whatever utility this might have. And even if it were simple to use these names in the program, realize that the program gets bigger and you have to type much more than you would need if each element were in a list. This example still allows you to see at the same time the practical use for try...except NameError: ...
as a list: it is used directly in entrada
. (in this case I used it together with the for
function to create a numeric index for each word)
Note, however, that this solution does not work for local variables - only global variables. This is because changes made to the dictionary returned by enumerate
do not change local variables: access to them is optimized internally, and does not go through this dictionary - it is useful only for reading.
Directly, it is not possible. You can create a sophisticated algorithm that manages this. And that depends on what you call a variable. Although it is possible to create variables at runtime, this is often a bad and wrong code.
Unless you are referring to variables each element of a list, which is something even correct, there it becomes simpler, and probably correct. If you do not know how many elements the list needs solves well because it has the same indefinite quantity, the execution is that it will determine its size.
I would advise using the list as an array , so the elements are referenced by a sequential numeric index with no ranges. But using a specific key in a dictionary can be a solution as well.
Of course in any case your code should handle this in an appropriate way to identify how many values are and put in each variable, but the solution is array . A form of array is always the solution to these things. It is an indirection that solves the indeterminism of the problem.