Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 3.8 assignment expression in a list comprehension

I'm trying to use the new assignment expression for the first time and could use some help.

Given three lines of log outputs:

sin = """Writing 93 records to /data/newstates-900.03-07_07/top100.newstates-900.03-07_07/Russia.seirdc.March6-900.12.csv ..
Writing 100 records to /data/newstates-900.03-07_07/top100.newstates-900.03-07_07/India.seirdc.March6-900.6.csv ..
Writing 100 records to /data/newstates-900.03-07_07/top100.newstates-900.03-07_07/US.seirdc.March6-900.15.csv ..
"""

The intent is to extract just the State (Russia, India and US) and the record count (93,100,100) . So the desired result is:

[['Russia',93],['India',100],['US',100]]

This requires the following steps to be translated into Python:

  • Convert each line into a list element
  • Split by space e.g. ['Writing', '93', 'records', 'to', '/data/newstates-900.03-07_07/top100.newstates-900.03-07_07/Russia.seirdc.March6-900.12.csv', '..']
  • Split the fifth such token by '/' and retain the last element: e.g. Russia.seirdc.March6-900.12.csv
  • Split that element by '.' and retain the first (0'th) element e.g. Russia

Here is my incorrect attempt:

import fileinput
y = [[ z[4].split('/')[-1].split('.')[0],z[1]] 
     for (z:=x.split(' ')) in 
     (x:=sin if sin else fileinput.input()).splitlines())]
like image 377
WestCoastProjects Avatar asked Feb 23 '26 01:02

WestCoastProjects


2 Answers

For what it's worth you can also get this using regex as well which would probably be more preferred/efficient.

[list(reversed(l)) for l in re.findall(r'Writing (\d+).+\/([A-Z,a-z]+)\.', sin)]

Or more accurately (to convert the int) and for readability (as per @chepner in comments):

[[country, int(count)] for count, country in re.findall(r'Writing (\d+).+\/([A-Z,a-z]+)\.', sin)]
like image 125
Jab Avatar answered Feb 24 '26 14:02

Jab


Is this good enough?

[[(wrds := line.split())[4].split("/")[-1].split('.')[0], wrds[1]] for line in sin.splitlines()]

I find using assignment expression redundant. You can also do this:

[[line.split('/')[-1].split('.')[0], line.split()[1]] for line in sin.splitlines()]
like image 37
ori6151 Avatar answered Feb 24 '26 13:02

ori6151



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!