我想找到一种优雅而有效的方法,将字符串中由空格分隔的单个字母数字字符的所有连续出现连接成单词。这是我想要做的一个例子:
a = 'a b c zzz a yyy a 2 xxx 2 3 wwww a c'
Desired_result = 'abc zzz a yyy a2 xxx 23 wwww ac'
以下是我使用循环的内容,但我确信有一些优雅的解决方案。
def myFunc(instring):
b,result = instring.split(),''
for i,row in enumerate(b):
if i==0:
result = row
else:
if len(row) == 1 and len(b[i-1]) == 1 and \
row.isalnum() and b[i-1].isalnum():
result = result + row
else:
result = result + ' ' + row
else:
return result
a = 'a b c zzz a yyy a 2 xxx 2 3 wwww a c'
print myFunc(a)
a_punct = '! @ 23 xxx cv abd $ abcd a c #'
print myFunc(a_punct)
答案 0 :(得分:3)
这是一个正则表达式解决方案:
>>> a = 'a b c zzz a yyy a 2 xxx 2 3 wwww a c'
>>> re.sub(r'(?<=\b\w)\s+(?=\w\b)', '', a)
'abc zzz a yyy a2 xxx 23 wwww ac'
它删除任何前面有单个字母数字字符(\s+
)并后跟单个字母数字字符((?<=\b\w)
)的空格((?=\w\b)
)。 \w
是一个字母数字字符或下划线(仅用[a-zA-Z0-9]
替换为字母数字),\b
是一个字边界,可确保字母数字字符不会被跟踪/之前是另一个。
答案 1 :(得分:2)
from itertools import groupby
print(" ".join(["".join(v) if k == 1 else " ".join(v)
for k, v in groupby(a.split(), key=len)]))
abc zzz a yyy a2 xxx 23 wwww ac
如果您实际上可以使用您自己的代码未检查的非单个字母数字字符,则可以使用lambda:
key=lambda x: len(x) == 1 and x.isalnum()
答案 2 :(得分:0)
那么,这取决于你对优雅的定义。您可以迭代split
的结果,将长度为1的项目构建为更大的项目,并直接附加更长的项目。
current_item = []
result = []
for item in instring.split():
if len(item) == 1:
current_item.append(item)
elif len(item) > 1 and current_item:
result.append("".join(current_item))
current_item = []
result.append(item)
else:
result.append(item)
if current_item:
result.append("".join(current_item))
print " ".join(result)
通过将项目创建为列表并在最后加入它们,可以避免大量的字符串连接,这在python中非常低效。由于字符串是不可变对象,因此每次使用+
运算符进行字符串连接时,都会在内存中创建一个新字符串,并将两个原始字符串的内容复制到其中。
另一方面,列表可以动态地改变大小,你只需要在最后创建一次字符串对象。
答案 3 :(得分:0)
test_string = 'a b c zzz a yyy a 2 xxx 2 3 wwww a c'
def join(l, r):
if r.isalnum() and len(r) == 1:
return l + r
else:
return l + ' ' + r + ' '
def collapseSingle(in_string):
return reduce(join, in_string.split(' '))
test_out = collapseSingle(test_string)
功能性解决方案。