Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List comprehensions splitting loop variable

Tags:

I am trying to find out if there is a way to split the value of each iteration of a list comprehension only once but use it twice in the output.

As an example of the problem I am trying to solve is, I have the string:

a = "1;2;4\n3;4;5" 

And I would like to perform this:

>>> [(x.split(";")[1],x.split(";")[2]) for x in a.split("\n") if x.split(",")[1] != 5] [('2', '4'), ('4', '5')] 

Without the need for running split three times. So something like this (Which is obviously invalid syntax but hopefully is enough to get the message across):

[(x[1],x[2]) for x.split(";") in a.split("\n") if x[1] != 5] 

In this question I am not looking for fancy ways to get the 2nd and 3rd column of the string. It is just a way of providing a concrete example. I could for course for the example use:

[x.split(";")[1:3] for x in a.split("\n")] 

The possible solutions I have thought of:

  1. Not use a list comprehension
  2. Leave it as is
  3. Use the csv.DictReader, name my columns and something like StringIO to give it the input.

This is mostly something that would be a nice pattern to be able to use rather than a specific case so its hard to answer the "why do you want to do this" or "what is this for" kind of questions

Update: After being reading the solution below I went and ran some speed tests. And I found in my very basic tests that the solution provided was 35% faster than the naive solution above.

like image 719
Nick Avatar asked Apr 25 '12 03:04

Nick


People also ask

Are list comprehensions for loops?

List comprehensions are also more declarative than loops, which means they're easier to read and understand. Loops require you to focus on how the list is created. You have to manually create an empty list, loop over the elements, and add each of them to the end of the list.

How do you split list comprehension in Python?

To split the elements of a list in Python: Use a list comprehension to iterate over the list. On each iteration, call the split() method to split each string. Return the part of each string you want to keep.

Does split () Create a list?

The split() method splits a string into a list. You can specify the separator, default separator is any whitespace.

Are list comprehensions better than for loops?

Because of differences in how Python implements for loops and list comprehension, list comprehensions are almost always faster than for loops when performing operations.


2 Answers

You could use a list comprehension wrapped around a generator expression:

[(x[1],x[2]) for x in (x.split(";") for x in a.split("\n")) if x[1] != 5] 
like image 57
ricochet1k Avatar answered Oct 01 '22 13:10

ricochet1k


Starting 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 twice the same expression:

In our case, we can name the evaluation of line.split(';') as a variable parts while using the result of the expression to filter the list if parts[1] is not equal to 5; and thus re-use parts to produce the mapped value:

# text = '1;2;4\n3;4;5' [(parts[1], parts[2]) for line in text.split('\n') if (parts := line.split(';'))[1] != 5] # [('2', '4'), ('4', '5')] 
like image 42
Xavier Guihot Avatar answered Oct 01 '22 13:10

Xavier Guihot