【问题标题】:Reading a line from a file and spliting the string从文件中读取一行并拆分字符串
【发布时间】:2025-11-23 16:45:03
【问题描述】:

希望你能回答我的问题。 我是 python 新手,所以我请求你的帮助。 我想打开一个包含以下行的文件。我想读取每一行并将它的每个字符作为字符串存储到列表中。

A B 2

A E 2

A W 1

B D 5

B W 4

B C 2

B F 3

C F 7

C V 9

D E 1

D J 7

E K 3

F L 2

F M 7

F R 3

F Y 1

G K 8

G J 5

我想像这样存储每一行​​的信息: [A B 2],[A E 2] 将是 ['A','B','2'],['A','E','2']

【问题讨论】:

  • 您是以 .txt 文件还是 .csv 格式读取它,如果是这样,您可以将分隔符/定界符声明为空格。然后,您可以将数字列更改为 str after 以获得所需的输出。

标签: python list file split


【解决方案1】:

您可以执行以下操作:

with open('testfile.txt') as fp:
    content = [elem
               for line in fp.readlines()
               for elem in [line.split()]
               if elem]
    print(content)

这会产生

[['A', 'B', '2'], ['A', 'E', '2'], ['A', 'W', '1'], ['B', 'D', '5'], ['B', 'W', '4'], ['B', 'C', '2'], ['B', 'F', '3'], ['C', 'F', '7'], ['C', 'V', '9'], ['D', 'E', '1'], ['D', 'J', '7'], ['E', 'K', '3'], ['F', 'L', '2'], ['F', 'M', '7'], ['F', 'R', '3'], ['F', 'Y', '1'], ['G', 'K', '8'], ['G', 'J', '5']]

【讨论】:

  • line.split() 会自动在空白处分割
  • 嗨!它打印这样的元素: ['A B 2\n', 'A E 2\n', 'A W 1\n', 'B D 5\n', 'B w 4\n', 'B C 2\n', 'B F 3\n', 'C F 7\n', 'C V 9\n', 'D E 1\n', 'D J 7\n'] 所以并非如此
  • @loukous:对。改了,看答案。
  • @MateenUlhaq:最好使用嵌套推导来再次遍历整个列表。
  • @MateenUlhaq 我在答案中添加了速度测试。 map(str.strip, f) 构造似乎是最快的。
【解决方案2】:

或者,作为显式循环:

data = []

with open(filename) as f:
    for line in f:
        line = line.rstrip()
        if line == '':
            continue
        data.append(line.split())

【讨论】:

  • 做过任何速度测试 (+1) 吗?
  • 我在答案中添加了速度测试
【解决方案3】:

我比较了这里的建议(3 个带有列表理解,另外 3 个带有 for 循环迭代并附加到列表):

def f_jan(filename):
    with open(filename) as f:
        return [
            elem
            for line in f.readlines()
            for elem in [line.split()]
            if elem]

def f_mateen_ulhaq_1(filename):
    with open(filename) as f:
        return [
            elem.split()
            for elem in map(str.rstrip, f)
            if elem]

def f_ralf_1(filename):
    with open(filename) as f:
        return [
            line.split()
            for line in f
            if line != '\n']

def f_mateen_ulhaq_2(filename):
    data = []
    with open(filename) as f:
        for line in f:
            line = line.rstrip()
            if line == '':
                continue
            data.append(line.split())

    return data

def f_mateen_ulhaq_3(filename):
    data = []
    with open(filename) as f:
        for line in f:
            if line == '\n':
                continue
            data.append(line.split())

    return data

def f_ralf_2(filename):
    data = []
    with open(filename) as f:
        for line in f:
            if line != '\n':
                data.append(line.split())

    return data

我创建了 2 个文件,一个包含 100 行问题中提供的示例输入,另一个文件包含 100.000 行相同的输入。

我测试了它们都返回相同的数据:

filename_1 = 'test_100_lines.txt'
assert (f_jan(filename_1)
        == f_mateen_ulhaq_1(filename_1)
        == f_ralf_1(filename_1)
        == f_mateen_ulhaq_2(filename_1)
        == f_mateen_ulhaq_3(filename_1)
        == f_ralf_2(filename_1))

然后,使用timeit,我比较了速度(对于大文本文件使用较少的重复次数):

for fn, number in[
    ('test_100_lines.txt', 10000),
    ('test_100000_lines.txt', 100),
]:
    for func in [
            f_jan,
            f_mateen_ulhaq_1,
            f_ralf_1,
            f_mateen_ulhaq_2,
            f_mateen_ulhaq_3,
            f_ralf_2,
    ]:
        t = timeit.timeit('func(fn)', 'from __main__ import fn, func', number=number)
        print('{:25s} {:20s} {:10.4f} seconds'.format(fn, func.__name__, t))

大小输入最快的解决方案是f_ralf_1(没有.strip()的列表理解,只是与\n比较):

test_100_lines.txt        f_jan                    0.5019 seconds
test_100_lines.txt        f_mateen_ulhaq_1         0.4483 seconds
test_100_lines.txt        f_ralf_1                 0.3657 seconds
test_100_lines.txt        f_mateen_ulhaq_2         0.4523 seconds
test_100_lines.txt        f_mateen_ulhaq_3         0.3854 seconds
test_100_lines.txt        f_ralf_2                 0.3886 seconds

test_100000_lines.txt     f_jan                    3.1178 seconds
test_100000_lines.txt     f_mateen_ulhaq_1         2.6396 seconds
test_100000_lines.txt     f_ralf_1                 1.8084 seconds
test_100000_lines.txt     f_mateen_ulhaq_2         2.7143 seconds
test_100000_lines.txt     f_mateen_ulhaq_3         2.0398 seconds
test_100000_lines.txt     f_ralf_2                 2.0246 seconds

【讨论】:

  • 我认为使用rstrip 而不是strip,您的版本会获得稍快的结果。 :) 实际上,另一个想法是在空行上完全避免 rstrip 调用开销,并通过 line == '\n' 进行比较。
  • @MateenUlhaq 在我的测试中,使用.strip().rstrip() 没有明显区别,所以我认为这不是重要的部分
  • @MateenUlhaq 与\n 而不是.strip() 进行比较是对的。我用新的测量更新了我的答案。