使用'\ n'.join(generator)时添加尾随分隔符

时间:2018-09-09 09:26:41

标签: python python-3.x

前言:类似于Create lines of text, '\n'.join(my_list) is missing trailing newline :-(,除了这里是生成器,而不是列表。

我需要从生成器函数中生成一个文本文件,以产生不以行结尾的单个字符串行。

我认为构建这样的字符串的推荐方法是(假设a = ['a', 'b', 'c', 'd', 'e'] n_items = len(a) n_max_look_forward = 2 unique_combos = [] for i, item in enumerate(a): for j in range(i+1, min(i+n_max_look_forward+1, n_items)): unique_combos.append( item+a[j] ) print(unique_combos) 是生成器对象)

g

但是,它将错过结尾的换行符。

下面是使用'\n'.join(g) 而不是','的示例:

'\n'

当然,我可以在结尾处手动>>> g=(str(i) for i in range(0,10)) >>> ','.join(g) '0,1,2,3,4,5,6,7,8,9' ,但是我相信这样做可能会变得昂贵。

我尝试使用+ '\n'附加一个空字符串,但这产生了令人惊讶的结果:

itertools.chain()

我该怎么做呢? >>> import itertools >>> g=itertools.chain((str(i) for i in range(0,10)),'') >>> ','.join(g) '0,1,2,3,4,5,6,7,8,9' 真的那么贵吗?

1 个答案:

答案 0 :(得分:1)

您可能会惊讶地听到,但是将生成器转换为列表,附加空("")值并使用str.join将是您最快的方法。

我喜欢您的想法,您希望使用生成器来提高效率,但是"".join实际上在加入之前将genexp内部转换为列表。这样做的原因是因为它需要测量最终字符串的长度并相应地分配内存。这样,它将在生成器上进行两次传递(基本上是创建一个列表以临时保存值)

py -3 -m timeit "''.join([str(i) for i in range(100000)])"
10 loops, best of 5: 29.6 msec per loop

py -3 -m timeit "''.join((str(i) for i in range(100000)))"
10 loops, best of 5: 32.3 msec per loop

也占用相同的内存。