当我执行以下列表理解时,我最终得到嵌套列表:
channel_values = [x for x in [ y.split(' ') for y in
open(channel_output_file).readlines() ] if x and not x == '\n']
基本上我有一个由以下内容组成的文件:
7656 7653 7649 7646 7643 7640 7637 7634 7631 7627 7624 7621 7618 7615
8626 8623 8620 8617 8614 8610 8607 8604 8600 8597 8594 8597 8594 4444
<snip several thousand lines>
此文件的每一行都以新行终止。
基本上我需要将每个数字(它们都用一个空格分隔)添加到一个列表中。
有没有更好的方法通过列表理解来做到这一点?
答案 0 :(得分:16)
您不需要列表推导:
channel_values = open(channel_output_file).read().split()
答案 1 :(得分:6)
这样做:
channel_values = open(channel_output_file).read().split()
split()将根据包含' ' '\t' and '\n'
的空白进行拆分。它会将所有值分成一个列表。
如果你想要整数值,你可以这样做:
channel_values = map(int, open(channel_output_file).read().split())
或列表推导:
channel_values = [int(x) for x in open(channel_output_file).read().split()]
答案 2 :(得分:2)
此外,原始列表理解具有嵌套列表的原因是因为您使用内部方括号集添加了额外级别的列表理解。你的意思是:
channel_values = [x for x in y.split(' ') for y in
open(channel_output_file) if x and not x == '\n']
其他答案仍然是编写代码的更好方法,但这就是问题的原因。
答案 3 :(得分:0)
另一个问题是你要打开文件。请注意,open
是file
的别名。
试试这个:
f = file(channel_output_file)
channel_values = f.read().split()
f.close()
请注意它们将是字符串值,因此如果您想要整数,则将第二行更改为
channel_values = [int(x) for x in f.read().split()]
如果文件中有非整数值,则 int(x)将抛出ValueError
。
答案 4 :(得分:0)
有没有更好的方法通过列表理解来做到这一点?
排序..
使用.readlines()
方法,您只需使用.read()
,而不是将每一行作为数组读取:
channel_values = [x for x in open(channel_output_file).readlines().split(' ')
if x not in [' ', '\n']]
如果你需要做更复杂的事情,特别是如果它涉及多个列表推导,你几乎总是更好地将它扩展为常规的for
循环。
out = []
for y in open(channel_output_file).readlines():
for x in y.split(' '):
if x not in [' ', '\n']:
out.append(x)
或者使用for循环和列表理解:
out = []
for y in open(channel_output_file).readlines():
out.extend(
[x for x in y.split(' ')
if x != ' ' and x != '\n'])
基本上,如果你不能简单地使用列表理解(或者需要嵌套它们),列表推导可能不是最好的解决方案。
答案 5 :(得分:0)
如果您不关心悬挂文件引用,并且您确实必须同时将一个列表读入内存,则其他答案中提到的单行程确实有效:
channel_values = open(channel_output_path).read().split()
在生产代码中,我可能会使用一个生成器,如果你不需要它们,为什么要读取所有这些行呢?
def generate_values_for_filename(filename):
with open(filename) as f:
for line in f:
for value in line.split():
yield value
如果您确实需要执行除迭代值之外的其他操作,则可以随后创建列表:
channel_values = list(generate_values_for_filename(channel_output_path))