我在Python 2.7中工作。我正在尝试创建一个函数,它可以将字符串压缩成一个更大的字符串,从任意索引开始,并以任意步骤开始。
例如,我可能希望将字符串@#*#*
压缩到较大的字符串TNAXHAXMKQWGZESEJFPYDMYP
,从5 th 字符开始,步长为3.结果字符串应该是:
TNAXHAX@MK#QW*GZ#ES*EJFPYDMYP
我想出的工作功能是
#Insert one character of string every nth position starting after ith position of text
text="TNAXHAXMKQWGZESEJFPYDMYP"
def zip_in(string,text,i,n):
text=list(text)
for c in string:
text.insert(i+n-1,c)
i +=n
text = ''.join(text)
print text
此功能可产生所需的效果,但我觉得它并不像它那样优雅。
此外,我希望它足够通用,我可以向后拉一个字符串,也就是说,从文本的i th 位置开始,我想插入字符串一次一个字符,向后一步。
例如,我可能希望将字符串@#*#*
压缩到较大的字符串TNAXHAXMKQWGZESEJFPYDMYP
,从22 nd 位置开始,步长为-3。结果字符串应为:
TNAXHAXMKQW*GZ#ES*EJ#FP@YDMYP
使用我当前的功能,我可以通过设置 n 为负,但如果我想要-3的步长,我需要将 n 设置为-2。
所有这一切都引出了我的问题:
是否有更优雅(或Pythonic)的方式来实现我的目标?
以下是一些相关问题,但未提供一般性答案:
Pythonic way to insert every 2 elements in a string
Insert element in Python list after every nth element
Merge Two strings Together at N & X
答案 0 :(得分:0)
您可以使用itertools
和more_itertools
库中的某些功能(确保拥有它们)并将它们组合起来以获得结果:chunked
和izip_longest
。< / p>
# Parameters
s1 = 'ABCDEFGHIJKLMNOPQ' # your string
s2 = '@#@#' # your string of elements to add
int_from = 4 # position from which we start adding letters
step = 2 # we will add in elements of s2 each 2 letters
return_list = list(s1)[:int_from] # keep the first int_from elements unchanged
for letter, char in izip_longest(chunked(list(s1)[int_from:], step), s2, fillvalue=''):
return_list.extend(letter)
return_list.append(char)
然后通过执行以下操作来获取字符串:
''.join(return_list)
输出:
# For the parameters above the output is :
>> 'ABCDEF@GH#IJ@KL#MNOPQ'
izip_longest(chunked(list(s1)[int_from:], step), s2, fillvalue='')
返回什么?:
for letter, char in izip_longest(chunked(list(s1)[int_from:], step), s2, fillvalue=''):
print(letter, char)
>> Output
>> (['E', 'F'], '@')
(['G', 'H'], '#')
(['I', 'J'], '@')
(['K', 'L'], '#')
(['M', 'N'], '')
(['O', 'P'], '')
(['Q'], '')