在空列表上使用.insert

2024-04-19 01:30:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我是一个编程的初学者,我正在尝试弄清楚列表方法是如何工作的。为了练习,我写了一个小小的字符串扰码器和解码器。你知道吗

import random
sliced = []
keyholder = []
scrambled = []
decoded = []

def string_slicer(string):
    i = 0
    while i < len(string):
        sliced.append(string[i])
        i += 1

def string_scrambler(string):
    string = string_slicer(string)
    a = 0
    while len(scrambled) != len(sliced):
        value = len(sliced) - 1
        key = random.randint(0,value)
        if key in keyholder:
            continue
        else:
            scrambled.append(sliced[key])
            keyholder.append(key)
        continue

def string_decoder():
    x = 0
    for item in keyholder:
        decoded.insert(keyholder[x], scrambled[x])
        x += 1

string_scrambler('merhaba')
string_decoder()

print sliced
print keyholder
print scrambled
print decoded

当我测试它时,string\u scrambler()工作正常,但是string\u decoder()会给出随机结果。以下是一些示例:

C:\Python27\Exercises>python scrambler.py
['m', 'e', 'r', 'h', 'a', 'b', 'a']
[2, 6, 0, 1, 3, 5, 4]
['r', 'a', 'm', 'e', 'h', 'b', 'a']
['m', 'e', 'r', 'h', 'a', 'a', 'b']

C:\Python27\Exercises>python scrambler.py
['m', 'e', 'r', 'h', 'a', 'b', 'a']
[4, 5, 1, 0, 3, 2, 6]
['a', 'b', 'e', 'm', 'h', 'r', 'a']
['m', 'a', 'r', 'e', 'h', 'b', 'a']

C:\Python27\Exercises>python scrambler.py
['m', 'e', 'r', 'h', 'a', 'b', 'a']
[1, 4, 5, 2, 3, 0, 6]
['e', 'a', 'b', 'r', 'h', 'm', 'a']
['m', 'e', 'a', 'r', 'h', 'b', 'a']

我认为尝试使用.insert方法在空列表中添加某些项可能会导致此问题。但我不知道到底为什么。你知道吗


Tags: keypystringlendefpython27decodedprint
2条回答

请注意,您的许多功能根本不是必需的。你知道吗

>>> list("some string")
["s", "o", "m", "e", " ", "s", "t", "r", "i", "n", "g"]`
# just like your `string_slicer` function.

值得注意的是,您的方法的问题是您可能会尝试这样做,例如:

>>> lst = []
>>> lst.insert("after", 3)
>>> lst.insert("before", 2)
>>> lst
["after", "before"]

由于列表最初的长度为零,插入到结束点之后只会将其发送到列表的末尾。尽管3是一个比2更遥远的索引,但它的顺序并不正确,因为基本上您已经完成了

lst.append("after")
lst.append("before")

相反,你可以这样做:

scrambled = [''] * len(sliced)
# build a list of the same length as the cleartext sliced string

for idx, dest in enumerate(keyholder):
    scrambled[dest] = sliced[idx]

然后去解扰,做相反的事情

deciphered = [''] * len(scrambled)
for idx, dest in enumerate(keyholder):
    deciphered[idx] = scrambled[dest]

我使用的完整解决方案,包括一些其他技巧,是:

import random

def make_key(lst):
    return random.shuffle(range(len(lst)))

def scramble(lst, key):
    result = [''] * len(lst)
    for idx, dst in enumerate(key):
        result[dst] = lst[idx]
    return result

def unscramble(scrambled, key):
    return [scrambled[idx] for idx in key]

s = "merhaba"
key = make_key(list(s))

scrambled = scramble(list(s), key)
deciphered = unscramble(scrambled, key)

print(list(s))
print(key)
print(scrambled)
print(deciphered)

注意:这会删除你最初尝试学习的所有列表方法!您应该注意到这一点,因为它表明了一个事实,即列表方法很慢(除了appendpop),如果存在另一个同样可读的解决方案,您可能应该避免使用它们。你知道吗

我认为最好不要用list作为decoded的数据结构。 我将使用dict作为临时变量,下面是我的字符串解码器版本:

_decoded = dict()  # changed

def string_decoder():
    x = 0
    for item in keyholder:
        _decoded[keyholder[x]] = scrambled[x]  #changed
        x += 1

    return [value for key, value in sorted(_decoded.items())]  #changed

decoded = string_decoder()

顺便说一句,您对list.insert()有问题,因为您将值插入列表中不存在的位置,例如,将第4项添加到包含2个元素的列表中。你知道吗

行为示例:

>>> decoded = []
>>> decoded.insert(100, 'b')
>>['b']
>>> decoded.insert(99, 'a')
>>> decoded
['b', 'a']  # according to your code, you expect ['a', 'b'] because 99 is less than 100, but the list has not enough entries. So, the item is just appended to the end

相关问题 更多 >