1

当我执行以下列表理解时,我最终得到了嵌套列表:

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>

该文件的每一行都由一个新行终止。

基本上我需要将每个数字(它们都用一个空格分隔)添加到一个列表中。

有没有更好的方法通过列表理解来做到这一点?

4

6 回答 6

17

您不需要列表推导:

channel_values = open(channel_output_file).read().split()
于 2009-11-12T17:49:51.050 回答
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()]
于 2009-11-12T17:50:20.600 回答
2

此外,原始列表理解具有嵌套列表的原因是因为您使用内部方括号集添加了额外级别的列表理解。你的意思是:

channel_values = [x for x in y.split(' ') for y in
    open(channel_output_file) if x and not x == '\n']

其他答案仍然是编写代码的更好方法,但这就是问题的原因。

于 2009-11-12T18:03:37.390 回答
1

如果您不关心悬空的文件引用,并且您确实必须一次将一个列表全部读入内存,那么其他答案中提到的单行代码确实有效:

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))
于 2009-11-13T02:38:25.960 回答
0

另一个问题是你让文件保持打开状态。请注意,这openfile.

试试这个:

f = file(channel_output_file)
channel_values = f.read().split()
f.close()

请注意,它们将是字符串值,因此如果您想要整数值,请将第二行更改为

channel_values = [int(x) for x in f.read().split()]

ValueError如果文件中有非整数值,int(x) 将抛出 a 。

于 2009-11-12T17:56:12.100 回答
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'])

基本上,如果您不能简单地使用列表推导(或需要嵌套它们)来做某事,那么列表推导可能不是最好的解决方案。

于 2009-11-12T18:12:48.853 回答