我有一个简单的Python函数,可以在其中交换字符串中的值。我这样做是通过生成一个伪随机整数,然后将其与下一个索引或上一个索引交换来避免超出范围的异常。
但是,我得到TypeError: string indices must be integers
。当我添加一条打印语句以检查由secrets.randbelow()
函数生成的索引的类型时,它返回class 'int'
,而我期望type 'int'
。这是引起错误的原因吗?
功能
import secrets as random
def shuffle_sequence(sequence):
sequence_len = int(len(sequence))
for x in range(0, sequence_len):
swap_index = random.randbelow(sequence_len)
next_index = 0
if swap_index != sequence_len:
next_index = swap_index + 1
else:
next_index = swap_index - 1
sequence[swap_index, next_index] = sequence[next_index, swap_index]
x += 1
return sequence
我什至在函数的第一行添加了一个int转换,希望这会有所帮助,但是它返回的是同一类int
,这是预期的。
为明确起见,sequence
是由字母,数字和符号组成的字符串。
答案 0 :(得分:1)
您不能使用元组为列表建立索引。使用两个单独的索引操作来交换两个索引:
sequence[swap_index], sequence[next_index] = sequence[next_index], sequence[swap_index]
请注意,您的测试swap_index != sequence_len
永远不会是正确的,因为secrets.randbelow()
已经保证您得到的参数值介于0到以下之间。当swap_index
等于sequence_len - 1
时,您会遇到索引错误,因为next_index
被设置为等于sequence_len
,这不是有效的索引。>
接下来,如果sequence
是不可变的类型,例如字符串,那么分配给索引将不起作用。您必须先将字符串转换为可变序列,例如列表,然后再转换回字符串(使用str.join()
)。
最后,您的实现仅直接交换连续的元素,这实际上不是适当的改组。您需要考虑所有尚未交换的元素。
最后,要“安全地”整理序列,只需使用secrets.SystemRandom()
类并将其命名为shuffle()
method:
from secrets import SystemRandom
sysrandom = SystemRandom()
def shuffle_sequence(sequence):
sequence = list(sequence)
sysrandom.shuffle(sequence)
return ''.join(sequence)
implementation for Random.shuffle()
反向遍历序列的索引,并挑选出位于迭代索引之前的随机元素:
for next_index in reversed(range(1, sequence_len)):
swap_index = random.randbelow(next_index)
sequence[swap_index], sequence[next_index] = sequence[next_index], sequence[swap_index]
答案 1 :(得分:0)
这里有两个问题:
您需要将字符串扩展到列表,在那里进行交换,然后将列表元素重新组合成字符串。
def shuffle_sequence(sequence):
# "abc" -> ["a", "b", "c"]
elements = list(sequence)
sequence_len = int(len(sequence))
for x in range(0, sequence_len):
swap_index = random.randbelow(sequence_len)
next_index = 0
if swap_index != sequence_len:
next_index = swap_index + 1
else:
next_index = swap_index - 1
# Swap elements of the list
elements[swap_index], elements[next_index] = elements[next_index], elements[swap_index]
x += 1
# Combine the elements into a single string
return ''.join(elements)