从TSV文件中链式读取列表

1 投票
3 回答
2194 浏览
提问于 2025-04-18 01:41

我有一个tsv文件,里面包含了一些链接的路径,每个链接之间用';'分隔。我想要使用:

在下面的例子中,我们可以看到文件中的文本是分开的,我只想读取最后一列,这一列的路径是以'14th'开头的。

6a3701d319fc3754    1297740409  166    14th_century;15th_century;16th_century;Pacific_Ocean;Atlantic_Ocean;Accra;Africa;Atlantic_slave_trade;African_slave_trade    NULL
3824310e536af032    1344753412  88     14th_century;Europe;Africa;Atlantic_slave_trade;African_slave_trade  3
415612e93584d30e    1349298640  138    14th_century;Niger;Nigeria;British_Empire;Slavery;Africa;Atlantic_slave_trade;African_slave_trade

我想把这个路径分割成一个链条,像这样:

['14th_century', 'Niger', 'Nigeria'....] 

我该怎么读取这个文件,并且去掉前面3列,只保留最后一列呢?

更新:

我现在尝试了这个:

import re
with open('test.tsv') as f:
    lines = f.readlines()
for line in lines[22:len(lines)]:
    re.sub(r"^\s+", " ", line, flags = re.MULTILINE)
    e_line = line.split(' ')
    real_line = e_line[0]
    print real_line.split(';')

但是问题是,它没有删除前面的3列?

3 个回答

1

你不需要用正则表达式来处理这个问题。Python的csv模块也可以处理以制表符分隔的文件:

import csv

filereader = csv.reader(open('test.tsv', 'rb'), delimiter='\t')
path_list = [row[3].split(';') for row in filereader]

print(path_list)
1

这是对你更新问题的回答。

但是问题是,它没有删除前3列吗?

这里有几个错误。

你的代码:

import re
with open('test.tsv') as f:
    lines = f.readlines()
for line in lines[22:len(lines)]:
    re.sub(r"^\s+", " ", line, flags = re.MULTILINE)
    e_line = line.split(' ')
    real_line = e_line[0]
    print real_line.split(';')

这一行没有任何作用……

re.sub(r"^\s+", " ", line, flags = re.MULTILINE)

因为 re.sub 函数并不会改变你的 line 变量,而是返回一个替换后的字符串。所以你可能想这样做。

line = re.sub(r"^\s+", " ", line, flags = re.MULTILINE)

而你的正则表达式 ^s\+ 只匹配以空格或制表符开头的字符串。因为你用了 ^。但我觉得你只是想把连续的空格或制表符替换成一个空格。所以,以上代码应该改成这样(只需去掉正则表达式中的 ^)。

line = re.sub(r"\s+", " ", line, flags = re.MULTILINE)

现在,每个字符串之间只用一个空格分隔。所以 line.split(' ') 就能按你想要的那样工作。

接下来, e_line[0] 返回 e_line 的第一个元素,也就是这一行的第一列。但你想跳过前3列,获取第4列。你可以这样做:

e_line = line.split(' ')
real_line = e_line[3]

好的,现在整个代码看起来是这样的。

for line in lines:#<---I also changed here because there is no need to skip first 22 lines in your example.
    line = re.sub(r"\s+", " ", line)
    e_line = line.split(' ')
    real_line = e_line[3]
    print real_line

输出:

14th_century;15th_century;16th_century;Pacific_Ocean;Atlantic_Ocean;Accra;Africa;Atlantic_slave_trade;African_slave_trade
14th_century;Europe;Africa;Atlantic_slave_trade;African_slave_trade
14th_century;Niger;Nigeria;British_Empire;Slavery;Africa;Atlantic_slave_trade;African_slave_trade

附注:

这一行可以写得更符合 Python 的风格。

之前:

for line in lines[22:len(lines)]:

之后:

for line in lines[22:]:

而且,你不需要使用 flags = re.MULTILINE,因为在循环中 line 是单行的。

2

如果第一个部分之间的分隔符只是一个空格,而不是一系列空格或者制表符,你可以这样做:

with open('file_name') as f:
    lines = f.readlines()
for line in lines:
    e_line = line.split(' ')
    real_line = e_line[3]
    print real_line.split(';')

撰写回答