避免 '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)压缩多个列表并自动填充它们。