在Python中将文本文件拆分成列和行

4

我有一个新手问题,需要帮助将文本文件分成列和行。假设我有这样一个文件:

1 2 3 4

2 3 4 5

我希望将其放入名为values = [[]]的二维列表中。

我可以获取行,这段代码运行良好:

values = map(int, line.split(','))

我不知道该如何描述同样的事情,但针对行和文档而言,说明文档没有任何意义。

谢谢。


1
@user654174,你的例子中没有逗号,而你却用逗号进行了分割。不一致。 - eyquem
5个回答

6
f = open(filename,'rt')
a = [[int(token) for token in line.split()] for line in f.readlines()[::2]]

在你提供的样本文件中,每个数据行之间都有一个空行 - 我已经考虑到了这一点,但如果你不想在数据中添加这个额外的行,则可以删除::2下标。
编辑:添加了转换为整数的内容 - 你也可以使用map,但是将列表推导和map混合使用似乎很丑陋。

1
如果没有空行,他也可以放弃readlines() - Björn Pollex
抱歉我有点迟钝,但是令牌(token)是什么意思? - user651474
这只是一个名称 - [int(token) for token in line.split()] 获取line.split()返回的列表中的每个元素,将其命名为 token并对其执行int(),从而形成另一个序列,其中包含一行中所有数字作为整数。我本可以选择任何其他名称。 - Alexander Gessler
@Alexander Gessler "file being a valid file handle i.e. obtained from open" 真是太可怕了!我们绝不能使用已经是内置对象名称的用户对象名称! - eyquem
@eyquem。这只是一个示例。我选择这个名称是为了明确表明我希望他在这里拥有一个文件句柄。@user。filename似乎是文件的路径,而不是打开的文件句柄!使用open(filename,'rt')来获取这样的句柄。 - Alexander Gessler
显示剩余12条评论

1
import csv
import itertools

values = []

with open('text.file') as file_object:
    for line in csv.reader(file_object, delimiter=' '):
        values.append(map(int, line))

print "rows:", values
print "columns"
for column in itertools.izip(*values):
    print column

输出为:

rows: [[1, 2, 3, 4], [2, 3, 4, 5]]
columns:
(1, 2)
(2, 3)
(3, 4)
(4, 5)

“我不知道如何表达同样的意思,但是针对行。” - eyquem

1

通过某种方法将数据输入到您的程序中。这里有一个:

f = open(tetxfile, 'r')
buffer = f.read()
f.close()

将缓冲区解析为表格(注意:strip()用于清除任何尾随空格):
table = [map(int, row.split()) for row in buffer.strip().split("\n")]

>>> print table
[[1, 2, 3, 4], [2, 3, 4, 5]]

也许你想要的是有序对,那么可以转置这个表格:

transpose = zip(*table)
>>> print transpose
[(1, 2), (2, 3), (3, 4), (4, 5)]

0
如果列由空格分隔
import re

A,B,C,D = [],[],[],[]
pat = re.compile('([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)')

with open('try.txt') as f:
    for line in f:
        a,b,c,d = pat.match(line.strip()).groups()
        A.append(int(a));B.append(int(b));C.append(int(c));D.append(int(d))

或使用csv模块

编辑

A,B,C,D = [],[],[],[]    
with open('try.txt') as f:
    for line in f:
        a,b,c,d = line.split()
        A.append(int(a));B.append(int(b));C.append(int(c));D.append(int(d))

但是,如果数据元素之间有多个空格,这段代码将失败。

编辑2

由于使用正则表达式的解决方案被认为极难理解,因此可以进行如下澄清:

import re

A,B,C,D = [],[],[],[]
pat = re.compile('\s+')

with open('try.txt') as f:
    for line in f:
        a,b,c,d = pat.split(line.strip())
        A.append(int(a));B.append(int(b));C.append(int(c));D.append(int(d))

2
这对于这个目的来说太复杂了。为所有事情使用正则表达式会使代码极难阅读。 - Alexander Gessler
此外,不使用原始字符串会导致正则表达式失败。通常来说 :-) - Alexander Gessler
@Alexander Gessler "不使用原始字符串会导致正则表达式失败"。但对我来说,我总是编写不带原始字符串的RE,我掌握了不使用原始字符串编写RE的技巧。事实上,我无法理解如何将原始字符串用作正则表达式..... - eyquem
re.compile('\s+') 之所以能够工作,是因为 \s 不是被识别的转义序列。因此,官方建议在指定正则表达式时始终使用原始字符串。 - Alexander Gessler
@Alexander Gessler:“re.compile('\s+')”只能正常工作是因为“\s”不是被识别的转义序列。对我来说,一个RE是一个字符串,用于search()、match()、compile()等等。re.compile('\\s+')同样可以工作,虽然**'\s'**是一个被转义的字符串。但它不是一个被转义的RE。呃呃… - eyquem
显示剩余11条评论

0
你可以尝试使用CSV-模块。你可以指定自定义分隔符,这样可能会起作用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接