我想缩小除第一行之外的多行字符串的所有行,而不包装文本。
例如,我想转:
A very very very very very very very very very very very very very very very very
long mutiline
string
成:
A very very very very very very very very very very very very very very very very
long multiline
string
我试过了
textwrap.fill(string, width=999999999999, subsequent_indent=' ',)
但这仍然将所有文字放在一行。想法?
答案 0 :(得分:14)
您只需要使用新行字符加上空格'\n'
替换换行符 '\n '
并将其保存到变量(因为replace
不会更改原始字符串,但返回一个新的替换品。)
string = string.replace('\n', '\n ')
答案 1 :(得分:2)
你的意思是这样的:
In [21]: s = 'abc\ndef\nxyz'
In [22]: print s
abc
def
xyz
In [23]: print '\n '.join(s.split('\n'))
abc
def
xyz
编辑或者(HT @Steven Rumbalski):
In [24]: print s.replace('\n', '\n ')
abc
def
xyz
答案 2 :(得分:0)
@steven-rumbalski提到的裸替换将是实现此目标的最有效方式,但这不是唯一的方法。
这是使用列表推导的另一种解决方案。如果文本已经拆分为行列表,则比运行join()
,replace()
和splitlines()
text = """A very very very very very very very very very very very very very very very very
long mutiline
string"""
lines = text.splitlines()
indented = [' ' + l for l in lines]
indented[0] = lines[0]
indented = '\n'.join(indented)
列表可以就地修改,但与使用第二个变量相比,性能成本显着。缩进所有行,然后在另一个操作中换出第一行也要快一点。
还有textwrap
模块。我不同意使用textwrap进行缩进是unpythonic。如果这些行在包含换行符的单个字符串中连接,则该字符串本身就会被包装。缩进是文本换行的逻辑扩展,因此textwrap对我有意义。
除了它很慢。真的,真的很慢。比15倍慢。
Python 3将indent
添加到textwrap
,这使得缩进而不重新包装非常容易。肯定有一种处理lambda谓词的更优雅方式,但这正是原始问题所要求的。
indented = textwrap.indent(text, ' ', lambda x: not text.splitlines()[0] in x )
以下是各种方法的一些timeit
结果。
>>> timeit.timeit(r"text.replace('\n', '\n ')", setup='text = """%s"""' % text)
0.5123521030182019
两个列表理解解决方案:
>>> timeit.timeit(r"indented = [' ' + i for i in lines]; indented[0] = lines[0]", setup='lines = """%s""".splitlines()' % text)
0.7037646849639714
>>> timeit.timeit(r"indented = [lines[0]] + [' ' + i for i in lines[1:]]", setup='lines = """%s""".splitlines()' % text)
1.0310905870283023
这是不幸的textwrap
结果:
>>> timeit.timeit(r"textwrap.indent(text, ' ', lambda x: not text.splitlines()[0] in x )", setup='import textwrap; text = """%s"""' % text)
7.7950868209591135
我认为有些时间可能是非常低效的谓词,但即使删除了它,textwrap.indent
仍然比裸替换慢8倍。
>>> timeit.timeit(r"textwrap.indent(text, ' ')", setup='import textwrap; text = """%s"""' % text)
4.266149697010405