我试图切片以下字符串,但我的代码没有返回任何超过第二个循环的内容。
s = "93011NULL 5011005874 A0000000000010000000000001JKL00000000NULL 00000000A63"
d = [5,20,20,1,16,9,3,8,50,8,1,2]
start = 0
for x in d:
print(s[start:x])
start += x
当我运行该代码时,我只得到:
43011
NULL
其余十个循环打印“”即空字符串。理想情况下,如果给定变量d中给出的字符串长度,它应该循环并将该字符串切片。
我可能做错了什么?
感谢。
答案 0 :(得分:4)
更新1
针对您的具体问题,解决方案如下所示:
s = "93011NULL 5011005874 A0000000000010000000000001JKL00000000NULL 00000000A63"
d = [5,20,20,1,16,9,3,8,50,8,1,2]
# Convert sizes to indexes
d = [sum(d[:i+1]) for i in range(len(d))]
splits = [s[i:j] for i, j in zip([0]+d, d+[None])]
print splits
<强>输出强>
>>>
['93011', 'NULL ', '5011005874 ', 'A', '0000000000010000', '000000001', 'JKL', '00000000', 'NULL ', '00000000', 'A', '63', '']
如果你需要切片,为什么不试试呢......
>>> s = 'AA111-99XYZ '
>>> d = [2, 4, 5, 8, 11]
>>> [s[i:j] for i, j in zip([0]+d, d+[None])]
['AA', '11', '1', '-99', 'XYZ', ' ']
<强>解释强>
zip
将多个列表作为参数,并从每个输入列表中生成一个包含i'th元素的集合列表。
>>> zip(d, d)
[(2, 2), (4, 4), (5, 5), (8, 8), (11, 11)]
我们需要[(0, 2), (2, 4), (4, 5), (5, 8), (8, 11), (11, None)]
。因此,列表元素需要转移索引。
>>> [0] + d
[0, 2, 4, 5, 8, 11]
>>> d + [None]
[2, 4, 5, 8, 11, None]
现在我们致电zip
>>> zip([0] + d, d + [None])
[(0, 2), (2, 4), (4, 5), (5, 8), (8, 11), (11, None)]
接下来,我们调用s[i:j]
,它会从索引i to j-1
提供幻灯片。
>>> s[0:2]
'AA'
>>> s[2:4]
'11'
因此,我们创建一个列表推导来为zip输出中的每个条目生成切片列表。
[ s[i:j] for i, j in zip([0] + d, d + [None]) ]
相当于
[ s[i:j] for i, j in [(0, 2), (2, 4), (4, 5), (5, 8), (8, 11), (11, None)] ]
最后一部分,s[i:None]
与s[i:]
答案 1 :(得分:3)
你的问题是你正在制作第二个索引大于第一个索引的切片。对于给定的d
值,您的切片如下:
第一次迭代:0,5
第二次迭代:5,20
第三次迭代:25,20&lt; - 这就是问题所在。
请注意,这是因为您只是不断添加到start
,因此它会越来越大。
如果要对字符串进行分区(即,有一组切片没有重叠,使得它们的串联等于原始字符串),而不是使用+=
,只需使用=
,设置d
,以便d
中的每个值都是您希望进行剪切的索引。 (请注意,这些索引必须按递增顺序排列。)
或者,如果您希望d
中的每个值表示分区中每个切片的大小,请使用以下代码:
for x in d:
print s[start:start+x]
start += x