[英]Python double list comprehension
I have a list of strings read from a file I need to turn into a 2D array:我有一个从文件中读取的字符串列表,我需要将其转换为二维数组:
IN >> lines = ['0.1;0;0;0;', '0.2;0;0;0;', '0.3;1;1;1;', '0.4;2;2;2;', '0.5;0;0;0;']
# Goes on for a few thousand lines
Note each string ends in ;
注意每个字符串都以
;
结尾;
. .
I need to exclude lines with all zeroes (some lines are all zeroes at the start and at the end)我需要排除全为零的行(有些行在开头和结尾都是零)
I .split()
on ;
我
.split()
上;
but filter
None
to remove the empty values I will get at the end of each returned array from the .split()
.但
filter
None
以删除我将从.split()
返回的每个数组末尾获得的空值。
data_array = [list(filter(None, line.split(';'))) for line in lines if line.split(';')[1] != '0']
OUT >> data_array = [[0.1, 0, 0, 0], [0.2, 0, 0, 0], [0.3, 1, 1, 1], [0.4, 2, 2, 2], [0.5, 0, 0, 0]]
This is kind of returning the 2D array I need, but including the arrays with all zeroes, so my conditional must be at the wrong place.这有点返回我需要的二维数组,但包括全为零的数组,所以我的条件必须在错误的地方。 Except I thought conditions at the end of a list comprehension filter the elements that go into the list.
除了我认为列表理解末尾的条件会过滤进入列表的元素。
Then I thought I needed to filter on the "inside" array:然后我想我需要过滤“内部”数组:
data_array = [[l for l in (filter(None, line.split(';'))) if l != '0'] for line in lines]
OUT >> data_array = [[0.1], [0.2], [0.3, 1, 1, 1], [0.4, 2, 2, 2], [0.5]]
Except this is removing the zeroes but leaving the marker (the first element of each array is a marker)除了这是删除零但留下标记(每个数组的第一个元素是一个标记)
What I'm looking to get is just the arrays that contain numbers but not zeroes我想要得到的只是包含数字但不包含零的数组
DESIRED OUTPUT >> data_array = [[0.3, 1, 1, 1], [0.4, 2, 2, 2]]
It is cleaner to do this over multiple lines and not using the filter(None, ...)
as you can just use line[:-1]
, to emit the last character.在多行上执行此操作而不使用
filter(None, ...)
更干净,因为您可以只使用line[:-1]
来发出最后一个字符。 First creating the list in lists, can be done by:首先在列表中创建列表,可以通过以下方式完成:
nested_list = [line[:-1].split(';') for line in lines]
You can then iterate over the inner lists to check if they contain a 0:然后,您可以遍历内部列表以检查它们是否包含 0:
filtered_list = [line for line in nested_list if '0' not in line]
Then we need to convert everything to floats:然后我们需要将所有内容转换为浮点数:
result = [list(map(float, line)) for line in filtered_list]
Or if you really want to have a one-liner:或者,如果你真的想要一个单线:
result = [list(map(float, line)) for line in [line[:-1].split(';') for line in lines] if '0' not in line]
[ x
for x in ([ float(v) for v in line.split(';') if v ]
for line in lines)
if any(x[1:]) ]
We have an inner generator which iterates all lines, splits each line, removes the empty strings and converts all remaining values to floats.我们有一个内部生成器,它迭代所有行,拆分每一行,删除空字符串并将所有剩余值转换为浮点数。 Then we have an outer loop which checks each of these results for containing only zeros by using the
any()
function on all but the first element.然后我们有一个外循环,它通过对除第一个元素之外的所有元素使用
any()
函数来检查这些结果中的每一个是否只包含零。
This produces all floats.这将产生所有浮点数。 If you need only the first element in each line to be a float and the rest shall be integers, then use this extension:
如果您只需要每行中的第一个元素是一个浮点数,其余的应该是整数,那么使用这个扩展:
[ x
for x in ([ (int if i else float)(v)
for i, v in enumerate(line.split(';'))
if v ]
for line in lines)
if any(x[1:]) ]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.