是否有一种优雅的方式(最有可能使用列表解析)来连接列表中的所有相邻字符串元素?
我有一个列表,其中一行中的多个字符串之间没有功能差异,并且所有这些字符串连接成一个字符串,但是为了可读性和等价测试,我想将它们连接在一起。列表中可以有其他非字符串元素可以分解字符串。这些需要保留在串联的字符串组之间。
例如,我可以
rule = ["a", "b", C(), "d", "ef", "g"]
相反,我想要
rule = ["ab", C(), "defg"]
答案 0 :(得分:3)
您可以使用itertools.groupby
和chain
完成此操作。
from itertools import groupby, chain
isstr = lambda x: isinstance(x, basestring)
# on Python 3: lambda x: isinstance(x, str)
rule = ["a", "b", C(), "d", "ef", "g"]
list(chain.from_iterable(
# join string groups into single-element sequence,
# otherwise just chain the group itself
(''.join(group), ) if group_isstr else group
for group_isstr, group in groupby(rule, isstr)
))
['ab', <__main__.C object at 0x108dfdad0>, 'defg']
答案 1 :(得分:3)
itertools.groupby
是基于共同特征组合元素的常用答案。在这种情况下,我们对元素的类型进行分组,当类型为str
时,我们将其折叠,否则我们直接从组中生成结果。作为“一线”,您可以这样做:
rule = ["a", "b", C(), "d", "ef", "g"]
rule = [x for cls, grp in itertools.groupby(rule, type)
for x in ((''.join(grp),) if cls is str else grp)]
假设C
是一个默认为__repr__
的类,您将获得如下输出:
['ab', <__main__.C at 0x1d572c98588>, 'defg']
在这种情况下,listcomp的“外部”循环正在生成共享类型和具有该类型的元素的迭代器。当类型为str
时,我们将组合字符串的单元素tuple
设为“迭代”(它只是一个元素,所以我们只迭代一次);当它不是str
时,我们会逐一生成该组的元素,而无需进一步处理。
答案 2 :(得分:0)
您可以使用itertools.groupby
:
import itertools
class C:
pass
rule = ["a", "b", C(), "d", "ef", "g"]
s = [(a, list(b)) for a, b in itertools.groupby(rule, type)]
new_s = [''.join(b) if all(isinstance(c, str) for c in b) else b[0] for a, b in s]
输出:
['ab', <__main__.C instance at 0x101419998>, 'defg']
答案 3 :(得分:0)
以基本方式使用此功能:
def concat_str(lst):
newlst = []
newstr = ""
length = len(lst)
for index, elem in enumerate(lst):
if(type(elem) is str):
newstr = newstr + elem
if(index == length -1):
newlst.append(newstr)
else:
if(newstr):
newlst.append(newstr)
newlst.append(elem)
newstr = ""
return newlst