for i in range(n):
for j in range(o):
orderedList.append(newStringList[j][i])
我是初学Python程序员
我有一个要解决的加密问题,我必须将一个字符串拆分为n个大小的块,然后将每个的第一个索引添加到列表中,然后将每个的第二个索引添加到其中,等等。我有一个解决方案可以解决问题但是,当所有块相等时,如果len(string)%n!= 0,则最后一个块有时可能会更小。当发生这种情况时,上面的循环我将列表中的字符添加到范围之外且程序没有工作。对此有什么解决方案吗?
修改
似乎我有点不清楚
加密采用字符串,例如“123456789”和数字n,例如3.然后将字符串分成大小为n的块。所以newStringList [123,456,789]。然后我从newStringList [0]获取第一个元素到newStringList [n-1],然后移动到第二个元素,依此类推。所以orderedList [1,4,7,2,5,8,3,6,9]。现在你有一个更好的背景来解决上述问题。
答案 0 :(得分:1)
这是一种简单的字符串分块方式,如果最后一个字符串太短,则不会介意:
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 ] )
答案 1 :(得分:1)
在最后一行之前添加一个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])
答案 2 :(得分:1)
有多种选择:
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函数(拼写为i for Python 2.7)来压缩多个列表并自动填充它们。