【问题标题】:How two write two nested lists column wise in .txt file?两个如何在 .txt 文件中逐列写入两个嵌套列表?
【发布时间】:2021-05-11 01:06:19
【问题描述】:

我有两个列表看起来像:

sentences = [['its', 'a', 'great', 'show'], ['nice', 'movie'], ['good', 'series']]
labels = [['O', 'O', 'O', 'B_A'], ['O', 'B_A'], ['O', 'B_A']]

我想将这对列表 按列 保存在 txt 文件中,因此每个元素对应该用空格分隔,每个列表对应该用一个空行。

想要的输出应该是这样的:

its O
a O
great O
show B_A

nice O
movie B_A

good O
series B_A

我试过这个:

filename = 'data.txt'

with open(filename, 'w') as f:
    for sen in sentences:
        for lab in labels:
            line = sen + ' ' + lab
            f.write(line)

我有以下错误:

TypeError: can only concatenate list (not "str") to list

更新:使用第一个答案,我试图定义一个函数,该函数采用两个嵌套列表和新文件名,如下所示:


def create_txt(ls1, ls2,file_name):
    with open(file_name, 'w') as f:
        for sen, lab in zip(ls1,ls2):
            for i, j in zip(sen, lab):
                f.write(f'{i} {j}')
            f.write('\n')
    return file_name

但是它将提供的文件名作为字符串返回:

create_txt(sentences, labels,'data_n.txt')

Output: 'data_n.txt'

我在这里做的逻辑问题是什么?

提前致谢!

【问题讨论】:

  • 这能回答你的问题吗? Python iterate over two lists simultaneously
  • 错误是不言自明的。您正在将列表连接到字符串。您需要使用zip 一起迭代两个主列表,然后再次使用zip 一起迭代子列表,打印对并在子列表迭代结束时打印换行符。写入文件无关紧要;如果可以打印,则可以将其替换为 f.write(string)
  • @ggorlen 我正在尝试,谢谢!

标签: python nested-lists txt


【解决方案1】:

您可以为此使用csv 模块。

import csv

with open("file.txt", "w", newline="\n") as fp:
    writer = csv.writer(fp, delimiter=" ")
    for sentence, label in zip(sentences, labels):
        for i, j in zip(sentence, label):
            writer.writerow([i, j])
        fp.write('\n')

不使用任何额外的模块

with open("file.txt", "w") as fp:
    for sentence, label in zip(sentences, labels):
        for i, j in zip(sentence, label):
            fp.write(f'{i} {j}\n')
        fp.write('\n')

【讨论】:

  • 谢谢 试过了,还是没有换行。
  • @AliF 立即尝试。
  • 为什么需要csv 模块呢?您应该能够只写出文件而无需任何额外的导入。
  • @Snackhole 你是对的。在不使用csv 模块的情况下添加了解决方案。
【解决方案2】:

另一个可行的答案,略有不同,有一些解释性的 cmets:

sentences = [['its', 'a', 'great', 'show'], ['nice', 'movie'], ['good', 'series']]
labels = [['O', 'O', 'O', 'B_A'], ['O', 'B_A'], ['O', 'B_A']]

filename = "data.txt"
outputstring = ""

# Construct the output string with zip.

# First we're zipping the elements of the source lists,
# which gives a sequence of pairs like this:
# (sentences[0], labels[0]), (sentences[1], labels[1]), etc.

# Then we iterate over that sequence and zip up the contents of
# each pair of lists in the same way, and concatenate those strings
# with the outputstring, followed by a single newline character.
# After that, an extra newline is added to break up the groups.

for sentence, label in zip(sentences, labels):
    for i, j in zip(sentence, label):
        outputstring += i + " " + j + "\n"
    outputstring += "\n"

# This removes the extra whitespace at the end.

outputstring = outputstring.rstrip()

# Finally, you can just write the string to your output file.

with open(filename, "w") as f:
    f.write(outputstring)

这是第二个不使用zip的例子:

sentences = [['its', 'a', 'great', 'show'], ['nice', 'movie'], ['good', 'series']]
labels = [['O', 'O', 'O', 'B_A'], ['O', 'B_A'], ['O', 'B_A']]

filename = "data.txt"
outputstring = ""

# Check the length of each list of lists and make sure they're the same:

sentenceslen = len(sentences)
labelslen = len(labels)

if sentenceslen != labelslen:
    print("Malformed data!")
    raise SystemExit

# Iterate over both lists using their lengths to define the range of indices.

for i in range(sentenceslen):
    
    # Check the lengths of each pair of sublists and make sure they're the same:
    
    subsentenceslen = len(sentences[i])
    sublabelslen = len(labels[i])
    
    if subsentenceslen != sublabelslen:
        print("Malformed data!")
        raise SystemExit
    
    # Iterate over each pair of sublists using their lengths to define the range of indices:
    
    for j in range(subsentenceslen):
        
        # Construct the outputstring by using both indices to drill down to the right strings,
        # ending with newline:
        
        outputstring += sentences[i][j] + " " + labels[i][j] + "\n"
    
    # Break up groups with newline again:
    
    outputstring += "\n"

# Remove whitespace at end:

outputstring = outputstring.rstrip()

# Write outputstring to file:

with open(filename, "w") as f:
    f.write(outputstring)

我不建议实际使用第二个示例中的代码。它不必要地复杂,但为了完整起见,我将其包括在内,并说明使用上面的zip 函数如何节省工作量。 zip 函数也不关心您是否提供不同长度的列表,因此如果您尝试这样做但不检查它,您的脚本不会崩溃;它会吐出不超过较小列表长度的值对,并忽略较大列表之后的值。

【讨论】:

  • 感谢您的精彩解释!我正在考虑将第一个代码转换为一个函数,该函数需要两个嵌套列表和新 txt 文件的名称。我可以使用函数来实现它们吗?还是因为使用with open(filename, 'w') as f: ...而无法实现?
  • 是的,应该可以正常工作。在函数中处理文件没什么特别的!
猜你喜欢
  • 2014-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-09
  • 1970-01-01
  • 2023-02-05
  • 2022-11-13
相关资源
最近更新 更多