将列表中的嵌入式列表写为文件中的行

时间:2018-10-11 21:33:31

标签: python python-3.x list

我有一个带有子列表的列表,每次都有一个字符串,另一个字符串,然后是一个由字符串组成的列表,如下所示:

big_list = [['sentence', 'translation', ['error1', 'error2','error3']], ['sentence','translation',['error1','error2']],['sentence','translation',['error1', 'error2','error3','error4']]]

,我想将每个嵌入列表打印在单独的一行上,列表中的元素由制表符分隔,嵌入列表中的元素用逗号分隔 像这样:

sentence   translation   error1, error2, error3
sentence   translation   error1, error2
sentence   translation   error1, error2, error3, error4

如果子列表中的所有元素都是字符串,则以下代码可以正常工作。

with open (outputfile, "w", encoding="utf-8") as f:
    f.writelines('\t'.join(i) + '\n' for i in big_list)

但是,由于子列表中的第三个元素是列表,它变得更加复杂,我不知道解决此问题的最佳方法是什么?

我能想到的就是先使用"".join(j) + "," for j in subsublist

将子列表中的嵌入列表首先转换为字符串。

所以我尝试了以下操作:

string_errors = ("".join(j) + "," for j in dict["trg_errors"])

但是它说类型是一个生成器对象,而不是字符串。 因此,我仍然无法使用我的writelines函数。 我如何使其成为字符串? 还有解决这个问题的更有效方法吗?

3 个答案:

答案 0 :(得分:3)

您可以在尝试注销之前转换为合理的数据结构。像这样的数据集的正常结构将是一个字符串元组,所以让我们考虑一下如何实现:

# pseudo-code:
[(sentence, translation, comma-separated_errors) for ? in big_list]

这将为我们提供所需的结构,但是如何从我们将要开始的错误列表中得到comma-separated_errors,以及?是什么呢?重新迭代?让我们一次看看那些。

您的错误列表是一个字符串列表,字符串迭代器具有方便的str.join方法将它们粘合在一起,因此", ".join(error_list)将为我们提供帮助。

big_list是一个列表列表,其中每个内部列表都是[sentence, translation, error_list]。通过列表解压缩很容易退出。

将所有内容放在一起,我们拥有:

lines = [(sentence, translation, ', '.join(error_list)) for sentence, translation, error_list in big_list]

一旦我们拥有正确的数据结构,就如同在'\t'.join(line) for line in lines中调用writelines一样简单。

with open("outputfile.tsv", 'w') as f:
    f.writelines("\t".join(line) for line in lines)

答案 1 :(得分:2)

在调用制表符联接之前,您可以构建一个新的字符串列表,然后调用它(您在想正确的方向):

for l in big_list:
    print('\t'.join(l[0:-1] + [', '.join(l[-1])]))

这部分', '.join(l[-1])l中的子列表转换为以逗号分隔的字符串。

答案 2 :(得分:0)

这就是我会做的

def get_rows(big_list):
    for small_list in big_list:
        colums = []
        for item in small_list:
            if isinstance(item, str):
                colums.append(item)
            elif isinstance(item, list):
                colums.append(', '.join(item))
        yield '\t'.join(colums)

with open ('tmp_big', "w", encoding="utf-8") as f:
    f.write('\n'.join(get_rows(big_list)))

def get_words(big_list):
    for small_list in big_list:
        for item in small_list:
            if isinstance(item, str):
                yield item + '\t'
            elif isinstance(item, list):
                yield ', '.join(item) + '\n'

 with open ('tmp_big', "w", encoding="utf-8") as f:
    f.write(''.join(get_words(big_list)))

将get_rows用作生成器将节省我们的空间,因为预计大型列表会很大。