避免 'index not in range' 在嵌套循环中加密字符串块
Avoid 'index not in range' on nested loops encrypting chunks of string
for i in range(n):
for j in range(o):
orderedList.append(newStringList[j][i])
我是初学者Python程序员
我有一个加密问题要解决,我必须将一个字符串分成 n 大小的块,然后将每个的第一个索引添加到列表,然后每个的第二个索引,等等。我有一个解决问题的方法但是,当所有块都相等时,如果 len(string)%n != 0,最后一个块有时会更小。发生这种情况时,我必须将字符添加到列表的上述循环超出范围,程序不会工作。有什么解决办法吗?
编辑
好像有点不清楚
加密采用字符串,例如“123456789”和一个数字 n e.g. 3.然后将字符串分成大小为n的块。所以 newStringList[123,456,789]。然后我将第一个元素从 newStringList[0] 取出到 newStringList[n-1],然后移动到第二个元素,依此类推。所以 orderedList[1,4,7,2,5,8,3,6,9]。现在您对上述问题有了更好的背景。
这是一种简单的字符串分块方法,如果最后一个分块太短,它不会介意:
def ChunkString( string, n=8 ):
return [ string[ i:i+n ] for i in range( 0, len( string ), n ) ]
例如:
>>> ChunkString('123456789')
['12345678', '9']
另一种可能适用于加密上下文的方法是在进入之前填充每个字符串,使其长度可以被 n
:
整除
def PadString( string, n=8, padChar='*' ):
return string + padChar * ( -len( string ) % n )
以下是一些示例输出:
>>> PadString('1')
'1*******'
>>> PadString('1234567')
'1234567*'
>>> PadString('12345678')
'12345678'
更新后的问题的解决方案如下所示:
chunks = ChunkString( '12345678', 3 )
from itertools import izip_longest, chain
reordered = chain( *izip_longest( *chunks ) )
print( [ x for x in reordered if x is not None ] )
在最后一行之前添加一个 if 条件将解决此问题。 if 条件是确保只有当元素存在时才访问数组列表。
for i in range(n):
for j in range(o):
if j < len(newStringList) and i < len(newStringList[j]) :
orderedList.append(newStringList[j][i])
有多个选项:
1) 请求原谅,a.k.a。使用 Exceptions:
for i in range(n):
for j in range(o):
try:
orderedList.append(newStringList[j][i])
except IndexError:
break
2) 将字符串填充到合适的长度:
if not len(inputStr) % n:
inputStr += '*' * (n - len(inputStr) % n)
3) 使用奇特的方法:
对于 Python 2.7:
a = [[1,2,3],[4,5,6],[7,8]]
orderedList = [filter(None,x) for x in itertools.izip_longest(*a)]
-> [(1, 4, 7), (2, 5, 8), (3, 6)]
和 Python 3.x:
a = [[1,2,3],[4,5,6],[7,8]]
orderedList = [list(filter(None,x)) for x in itertools.zip_longest(*a)]
-> [(1, 4, 7), (2, 5, 8), (3, 6)]
此方法使用 (i)zip_longest 函数(在 Python 2.7 中拼写为 i)压缩多个列表并自动填充它们。
for i in range(n):
for j in range(o):
orderedList.append(newStringList[j][i])
我是初学者Python程序员
我有一个加密问题要解决,我必须将一个字符串分成 n 大小的块,然后将每个的第一个索引添加到列表,然后每个的第二个索引,等等。我有一个解决问题的方法但是,当所有块都相等时,如果 len(string)%n != 0,最后一个块有时会更小。发生这种情况时,我必须将字符添加到列表的上述循环超出范围,程序不会工作。有什么解决办法吗?
编辑
好像有点不清楚
加密采用字符串,例如“123456789”和一个数字 n e.g. 3.然后将字符串分成大小为n的块。所以 newStringList[123,456,789]。然后我将第一个元素从 newStringList[0] 取出到 newStringList[n-1],然后移动到第二个元素,依此类推。所以 orderedList[1,4,7,2,5,8,3,6,9]。现在您对上述问题有了更好的背景。
这是一种简单的字符串分块方法,如果最后一个分块太短,它不会介意:
def ChunkString( string, n=8 ):
return [ string[ i:i+n ] for i in range( 0, len( string ), n ) ]
例如:
>>> ChunkString('123456789')
['12345678', '9']
另一种可能适用于加密上下文的方法是在进入之前填充每个字符串,使其长度可以被 n
:
def PadString( string, n=8, padChar='*' ):
return string + padChar * ( -len( string ) % n )
以下是一些示例输出:
>>> PadString('1')
'1*******'
>>> PadString('1234567')
'1234567*'
>>> PadString('12345678')
'12345678'
更新后的问题的解决方案如下所示:
chunks = ChunkString( '12345678', 3 )
from itertools import izip_longest, chain
reordered = chain( *izip_longest( *chunks ) )
print( [ x for x in reordered if x is not None ] )
在最后一行之前添加一个 if 条件将解决此问题。 if 条件是确保只有当元素存在时才访问数组列表。
for i in range(n):
for j in range(o):
if j < len(newStringList) and i < len(newStringList[j]) :
orderedList.append(newStringList[j][i])
有多个选项:
1) 请求原谅,a.k.a。使用 Exceptions:
for i in range(n):
for j in range(o):
try:
orderedList.append(newStringList[j][i])
except IndexError:
break
2) 将字符串填充到合适的长度:
if not len(inputStr) % n:
inputStr += '*' * (n - len(inputStr) % n)
3) 使用奇特的方法: 对于 Python 2.7:
a = [[1,2,3],[4,5,6],[7,8]]
orderedList = [filter(None,x) for x in itertools.izip_longest(*a)]
-> [(1, 4, 7), (2, 5, 8), (3, 6)]
和 Python 3.x:
a = [[1,2,3],[4,5,6],[7,8]]
orderedList = [list(filter(None,x)) for x in itertools.zip_longest(*a)]
-> [(1, 4, 7), (2, 5, 8), (3, 6)]
此方法使用 (i)zip_longest 函数(在 Python 2.7 中拼写为 i)压缩多个列表并自动填充它们。