Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

list comprehension replace for loop in 2D matrix

I try to use list comprehension to replace the for loop.

original file is

2 3 4 5 6 3
1 2 2 4 5 5
1 2 2 2 2 4

for loop

line_number = 0
for line in file:
    line_data = line.split()
    Cordi[line_number, :5] = line_data 
    line_number += 1

output is

[[2 3 4 5 6 3]
 [1 2 2 4 5 5]
 [1 2 2 2 2 4]]

if use list comprehension instead, for what I can think of is (I have to change the data type to int, so it can be plotted in later part of the program)

Cordi1= [int(x) for x in line.split() for line in data]

but the output is

[1, 1, 1]

but line.split() for line in data is actually a list, and if I try

Cordi1 = [int(x) for x in name of the list]

it works, why this happens?

like image 901
rankthefirst Avatar asked Aug 17 '14 02:08

rankthefirst


People also ask

Is list comprehension same as for loop?

List comprehensions are the right tool to create lists — it is nevertheless better to use list(range()). For loops are the right tool to perform computations or run functions. In any case, avoid using for loops and list comprehensions altogether: use array computations instead.

Why might you use a list comprehension instead of a loop?

List comprehensions are often not only more readable but also faster than using “for loops.” They can simplify your code, but if you put too much logic inside, they will instead become harder to read and understand.

Is list comprehension more efficient than for loop?

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

Which is faster lambda or list comprehension?

Actually, list comprehension is much clearer and faster than filter+lambda, but you can use whichever you find easier. The first thing is the function call overhead: as soon as you use a Python function (whether created by def or lambda) it is likely that the filter will be slower than the list comprehension.


1 Answers

You have the order of your loops swapped; they should be ordered in the same way they would be nested, from left to right:

[int(x) for line in data for x in line.split()]

This loops over data first, then for each line iteration, iterates over line.split() to produce x. You then produce one flat list of integers from these.

However, since you are trying to build a list of lists, you need to nest a list comprehension inside another:

Cordi1 = [[int(i) for i in line.split()] for line in data]

Demo:

>>> data = '''\
... 2 3 4 5 6 3
... 1 2 2 4 5 5
... 1 2 2 2 2 4
... '''.splitlines()
>>> [int(x) for line in data for x in line.split()]
[2, 3, 4, 5, 6, 3, 1, 2, 2, 4, 5, 5, 1, 2, 2, 2, 2, 4]
>>> [[int(i) for i in line.split()] for line in data]
[[2, 3, 4, 5, 6, 3], [1, 2, 2, 4, 5, 5], [1, 2, 2, 2, 2, 4]]

If you wanted a multidimensional numpy array from this, you can either convert the above directly to an array or create an array from the data then reshape:

>>> import numpy as np
>>> np.array([[int(i) for i in line.split()] for line in data])
array([[2, 3, 4, 5, 6, 3],
       [1, 2, 2, 4, 5, 5],
       [1, 2, 2, 2, 2, 4]])
>>> np.array([int(i) for line in data for i in line.split()]).reshape((3, 6))
array([[2, 3, 4, 5, 6, 3],
       [1, 2, 2, 4, 5, 5],
       [1, 2, 2, 2, 2, 4]])
like image 63
Martijn Pieters Avatar answered Oct 09 '22 02:10

Martijn Pieters