I want to use the assignment operator in a list comprehension. How can I do that?
The following code is invalid syntax. I mean to set lst[0]
to an empty string ''
if it matches pattern
:
[ lst[0] = '' for pattern in start_pattern if lst[0] == pattern ]
Thanks!
The Python language has distinct concepts for expressions and statements.
Assignment is a statement even if the syntax sometimes tricks you into thinking it's an expression (e.g.
a=b=99
works but is a special syntax case and doesn't mean that theb=99
is an expression like it is for example in C).List comprehensions are instead expressions because they return a value, in a sense the loop they perform is an incident and the main point is the returned list.
A statement can contain expressions but an expression cannot contain statements.
That said however list item assigment to is internally converted to a method call (to allow creation of list-like objects) and method calls are expressions. Therefore you can technically use list item assignment in an expression:
This is however considered bad because it harms readability and how easy is to read source code is the main focus in the Python language. You should write instead for example...
that by the way thanks to the
in
operator is equivalent to the even more readableList comprehensions are used for their return value and they make a loop internally... If what you want is the loop then just write a loop... whoever will read the code trying to understand what it does would appreciate that a lot (and whoever includes yourself in a few weeks).
It looks like you are confusing list comprehension with looping constructs in Python.
A list comprehension produces -- a list! It does not lend itself to a single assignment in an existing list. (Although you can torture the syntax to do that...)
While it isn't exactly clear what you are trying to do from your code, I think it is more similar to looping over the list (flow control) vs producing a list (list comprehension)
Loop over the list like this:
That is a reasonable way to do this, and is what you would do in C, Pascal, etc. But you can also just test the list for the one value and change it:
Or, if you don't know the index:
or, if you have a list of lists and want to change each first element of each sublist:
etc, etc, etc.
If you want to apply something to each element of a list, then you can look at using a list comprehension, or map, or one of the many other tools in the Python kit.
Personally, I usually tend to use list comprehensions more for list creation:
Which is more natural than:
But to modify that same list of lists, which is more understandable?
This:
or this:
YMMV
Here is a great tutorial on this.
In short: you don't. List comprehensions are for generating lists, not modifying existing lists. If you want to modify a list, use a for loop, as that's what they're for.
The Pythonic way to write that code would be something like:
However, if you really, really want to do assignment inside one, and don't mind every Python programmer who ever deals with your code hating it for all eternity, there are a few functions you can use:
If the variable you want to assign to is a global, then you can do
If the variable you want to assign to is a mutable sequence or a map (such as a list or a dict)
Python 3.8 will introduce Assignment Expressions.
It is a new symbol:
:=
that allows assignment in (among other things) comprehensions.It will introduce a lot of potential savings w.r.t. computation/memory, as can be seen from the following snippet of the above linked PEP (formatting adapted for SO):
This is already available in the recently releases alpha version (not recommended for production systems!). You can find the release schedule for Python 3.8 here.
If what you ment in the question is:
or for a list of patterns
This can actually be done easily
or for a list of patterns again
Maybe it isn't exactly what you're looking for, but I believe that it is worth to present this scenario.
Suppose that you have a
list
of dictionaries, like this:With a normal list comprehension, you might find the object that you're looking for:
As a result, you have a list with a single element, thanks to the
if
condition above.Therefore, you can index the only element, accessing one of the dictionary keys and assigning a value:
Here the result: