How can I use assignment operation in list comprehension in python and convert following iterative code into it?
For starters, you shouldn't be using list comprehensions for side-effects. List comprehensions are for expressing functional, mapping/filtering operations on arbitrary iterables to create a new list.
Furthermore, assignment expressions explicitly aren't allowed to be used for item-assignment (a[k] = b
), only simple assignment to a name (a = b
). So you could just use a function to use the assignment statement:
In [1]: def _reverse_helper(word, i):
...: length = len(word)
...: word[i] , word[(length-1)-i] = word[(length-1)-i] , word[i]
...:
In [2]: word = list("overflow")
...:
Now, it doesn't make any sense to re-assign the result of your list comprehension to word
again, because you are using the list comprehension for side-effects. So, doing something like this is the closest equivalent to your original implementation:
In [3]: [_reverse_helper(word, i) for i in range(len(word)//2)]
Out[3]: [None, None, None, None]
In [4]: word
Out[4]: ['w', 'o', 'l', 'f', 'r', 'e', 'v', 'o']
List comprehension with assignments
Assignments are statements, which are not allowed in list comprehensions, which support only expressions.
You can use sum
instead:
sources = {index: sum(1 for index in range(len(source)) if source == sources[index]) for source in data['Source']}
A more efficient method would be to use collections.Counter
, as @Amadan has suggested in the comments:
import collections.Counter:
sources = Counter(index for source in data['Source'] for index in range(len(source)) if source == sources[index])
How to set local variable in list comprehension?
Starting in Python 3.8
, and the introduction of assignment expressions (PEP 572) (:=
operator), it's possible to use a local variable within a list comprehension in order to avoid calling the same function twice.
In our case, we can name the evaluation of map_to_obj(v)
as a variable o
while using the result of the expression to filter the list; and thus use o
as the mapped value:
[o for v in [v1, v2, v3, v4] if (o := map_to_obj(v))]
Two assignments in single python list comprehension
When in doubt about efficiency use the timeit module, it's always easy to use:
import timeit
def f1(aRange):
x = [2*i for i in aRange]
y = [3*i for i in aRange]
return x,y
def f2(aRange):
x, y = zip(*[(2*i, 3*i) for i in aRange])
return x,y
def f3(aRange):
x, y = zip(*((2*i, 3*i) for i in aRange))
return x,y
def f4(aRange):
x = []
y = []
for i in aRange:
x.append(i*2)
y.append(i*3)
return x,y
print "f1: %f" %timeit.Timer("f1(range(100))", "from __main__ import f1").timeit(100000)
print "f2: %f" %timeit.Timer("f2(range(100))", "from __main__ import f2").timeit(100000)
print "f3: %f" %timeit.Timer("f3(range(100))", "from __main__ import f3").timeit(100000)
print "f4: %f" %timeit.Timer("f4(range(100))", "from __main__ import f4").timeit(100000)
The results seem to be consistent in pointing to the first option as the quickest.
f1: 2.127573
f2: 3.551838
f3: 3.859768
f4: 4.282406
list comprehension with multiple assignments
List comprehensions are great, but sometimes they're not best the solution, depending on requirements for readability and speed. Sometimes, just writing out the implied for loop (and if statement) is more readable and quicker.
def factors(n):
l = []
for i in range(1, int(n**0.5)+1):
if n % i == 0:
l.append(i)
l.append(n//i)
return l
For small numbers, the above function is quicker than the list comprehension. At larger numbers (1,000,000 and bigger), the function and list comprehension are equal in terms of speed.
For a slight speed increase you can also cache the append method of the list, though this makes the function slightly less readable.
def factors(n):
l = []
append = l.append
for i in range(1, int(n**0.5)+1):
if n % i == 0:
append(i)
append(n//i)
return l
Speed comparison:
In [86]: %timeit factors_list_comprehension(1000)
100000 loops, best of 3: 7.57 µs per loop
In [87]: %timeit factors_function(1000)
100000 loops, best of 3: 6.24 µs per loop
In [88]: %timeit factors_optimised_function(1000)
100000 loops, best of 3: 5.81 µs per loop
In [89]: %timeit factors_list_comprehension(1000000)
10000 loops, best of 3: 111 µs per loop
In [90]: %timeit factors_function(1000000)
10000 loops, best of 3: 108 µs per loop
In [91]: %timeit factors_optimised_function(1000000)
10000 loops, best of 3: 106 µs per loop
Can assignments be made as part of python list comprehension?
All you need to do is:
shod_l = [pd.DataFrame() for _ in shod_list]
or if using a variable q
:
shod_l = [pd.DataFrame() for q in shod_list]
or if you're determined to use a range:
shod_l = [pd.DataFrame() for q in range(len(shod_list))]
Related Topics
Pandas Group by and Find First Non Null Value for All Columns
Formatting Long Numbers as Strings in Python
How to Encrypt and Decrypt a String in Python
Convert Row to Column Header for Pandas Dataframe,
Getting Rid of Console Output When Freezing Python Programs Using Pyinstaller
In Python What Is a Global Statement
Comparing Previous Row Values in Pandas Dataframe
N-Grams in Python, Four, Five, Six Grams
Debugging (Displaying) SQL Command Sent to the Db by SQLalchemy
How to Hide the Console Window in a Pyqt App Running on Windows
How to Use Pip to Install a Package from a Private Github Repository
Rename Specific Column(S) in Pandas
Advanced Nested List Comprehension Syntax
What Is the Most Pythonic Way to Check If an Object Is a Number
Python Read from Subprocess Stdout and Stderr Separately While Preserving Order