Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Walrus operator in list comprehensions (python)

So when coding I really like to use list comprehensions to transform data and I try to avoid for loops. Now I discovered that the walrus operator can be really handy for this, but when I try to use it in my code it doesn't seem to work. I've got the following code and want to transform the strings containing data about the timestamps into datetime objects in one easy line, but I get an syntax error and I am not sure what the right syntax would be, does anyone know what I did wrong?

from datetime import datetime

timestamps = ['30:02:17:36',
              '26:07:44:25','25:19:30:38','25:07:40:47','24:18:29:05','24:06:13:15','23:17:36:39',
              '23:00:14:52','22:07:04:33','21:15:42:20','21:04:27:53',
              '20:12:09:22','19:21:46:25']

timestamps_dt = [
    datetime(days=day,hours=hour,minutes=mins,seconds=sec) 
    for i in timestamps
    day,hour,mins,sec := i.split(':')
] 

like image 437
Jeroen Vermunt Avatar asked Nov 26 '20 14:11

Jeroen Vermunt


People also ask

How do you use the walrus operator in Python?

Python 3.8 introduced a new walrus operator := . The name of the operator comes from the fact that is resembles eyes and tusks of a walrus of its side. The walrus operator creates an assignment expression. The operator allows us to assign a value to a variable inside a Python expression.

How does the walrus operator look in Python?

Assignment expression are written with a new notation (:=) . This operator is often called the walrus operator as it resembles the eyes and tusks of a walrus on its side. The assignment expression allows you to assign True to walrus , and immediately print the value.

Which version of Python has walrus?

The walrus operator was implemented by Emily Morehouse, and made available in the first alpha release of Python 3.8.


2 Answers

Since Walrus operator does not support values unpacking, the operation

day,hour,mins,sec := i.split(':')

is invalid.

Walrus operator is recommended to be used mostly in logic comparison, especially when you need to reuse a variable in comparison. Therefore, I would argue that for this case, a simple datetime.strptime() would be better for this case.

If you must use walrus comparison in your list comprehension, you may do

from datetime import datetime

timestamps = ['30:02:17:36',
              '26:07:44:25','25:19:30:38','25:07:40:47','24:18:29:05','24:06:13:15','23:17:36:39',
              '23:00:14:52','22:07:04:33','21:15:42:20','21:04:27:53',
              '20:12:09:22','19:21:46:25']

timestamps_dt = [
    datetime(2020,11, *map(int, time)) # map them from str to int
    for i in timestamps
    if (time := i.split(':')) # assign the list to the variable time
]
print(timestamps_dt)

But then it will lead to a question why not just,

timestamps_dt = [
    datetime(2020,11, *map(int, i.split(':'))) 
    for i in timestamps
]

Reference PEP-572

like image 70
burningalc Avatar answered Oct 23 '22 02:10

burningalc


...and want to transform the strings containing data about the timestamps into datetime objects in one easy line,

If you want to convert the list of strings into a list of datetime objects you can use the below one liner:

timestamps_dt = [datetime.strptime(d, '%d:%H:%M:%S') for d in timestamps]
like image 26
balderman Avatar answered Oct 23 '22 01:10

balderman