Python 如何按空格和行尾字符分割文件内容?

Python 如何按空格和行尾字符分割文件内容?,python,list-comprehension,Python,List Comprehension,当我执行以下列表理解时,我最终得到嵌套列表: 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

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

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>
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
其中,此文件的每一行都以新行终止

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


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

您不需要列表理解:

channel_values = open(channel_output_file).read().split()

您不需要对此列表进行理解:

channel_values = open(channel_output_file).read().split()
只要这样做:

channel_values = open(channel_output_file).read().split()
将根据包含
'\t'和'\n'
的空格进行拆分。它会将所有值拆分为一个列表

如果需要整数值,可以执行以下操作:

channel_values = map(int, open(channel_output_file).read().split())
或使用列表理解:

channel_values = [int(x) for x in open(channel_output_file).read().split()]
只要这样做:

channel_values = open(channel_output_file).read().split()
将根据包含
'\t'和'\n'
的空格进行拆分。它会将所有值拆分为一个列表

如果需要整数值,可以执行以下操作:

channel_values = map(int, open(channel_output_file).read().split())
或使用列表理解:

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

另一个问题是你把文件打开了。请注意,
open
文件的别名

试试这个:

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

另一个问题是您将文件保持打开状态。请注意,
open
文件的别名

试试这个:

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

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

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

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

另外,原始列表理解之所以有嵌套列表,是因为您使用了一组内方括号添加了额外的列表理解级别。你的意思是:

channel_values = [x for x in y.split(' ') for y in
    open(channel_output_file) if x and not x == '\n']
其他答案仍然是编写代码的更好方法,但这就是问题的原因

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

有点

使用
.readlines()
方法,您可以只使用
.read()
,而不是将每一行作为数组读取:

如果您需要做更复杂的事情,特别是当它涉及多个列表理解时,您几乎总是最好将其扩展为一个常规的
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'])
基本上,如果您不能简单地使用列表理解(或需要嵌套它们),那么列表理解可能不是最好的解决方案

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

有点

使用
.readlines()
方法,您可以只使用
.read()
,而不是将每一行作为数组读取:

如果您需要做更复杂的事情,特别是当它涉及多个列表理解时,您几乎总是最好将其扩展为一个常规的
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'])

基本上,如果您不能简单地使用列表理解(或需要嵌套它们),列表理解可能不是最好的解决方案。

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

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))

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

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))

我认为一旦您离开列表的范围,文件就会自动关闭?文件对象在被垃圾收集时被关闭,在没有引用时被垃圾收集。所以不,它不会让文件保持打开状态,因为行执行后没有对它的引用。谢谢,我担心了一会儿:)我以为一旦您离开列表的范围,文件就会自动关闭?当文件对象被垃圾回收时,它会被关闭,当没有对它的引用时,它会被垃圾回收。因此,它不会让文件保持打开状态,因为行执行后没有对它的引用。谢谢,我担心了一会儿:)您将此作为
open(channel\u output\u file)。readlines()
,但您真正需要的是
open(channel\u output\u file)
open()
返回的file对象作为一个迭代器,返回行
readlines()
将在每一行中发出咕噜声,这在这里是不需要的。我已编辑您的代码以删除“readlines()”。还投票给你+1。这将失败,因为你混淆了“x在…”和“y在…”的顺序。Python的嵌套列表理解语法是违反直觉的,除非您记得它模仿了您对没有理解的循环的正确顺序。另外,为什么不干脆split()并跳过对换行符的测试?(希望此评论不会出现多次-如果出现,请道歉)关于x和y的顺序,谢谢!这很令人困惑。我留在split()中的原因,以及Steve