在 Python while 循环中运行得太远的索引之一

One of the indexes running too far in a Python while loop

提问人:jvkloc 提问时间:3/7/2020 最后编辑:jvkloc 更新时间:3/7/2020 访问量:214

问:

我有一个函数,它应该计算每个长度的单词数,直到并包括任何给定文本中最长的单词。我被困在我的循环中。PyCharm 说道:

sana = sanat[i].strip(",.")  
IndexError: list index out of range

我不知道为什么变量 I 跑得太远了(如果这就是这里发生的事情)。这是在 Python 中,但这种问题实际上与语言没有任何关系。我将非常感谢任何帮助。

对于测试,文本是任意的。此外,打印件用于测试。

    teksti = "Har du någon tanken. Om inriktningsmöjligheten i matematik."

    def sanamaarat(merkkijono):
        sanat = merkkijono.split()
        sanat.sort(key=len)
        lista = []
        lista.append(0)
        apulista = []
        apulista2 = []

        for sana in sanat:
            sana = sana.strip(",.")
            pituus = len(sana)
            apulista.append(pituus)

        joukko = list(set(apulista))
        for numero in joukko:
            apulista2.append(apulista.count(numero))
        print(sanat)
        print(apulista2)
        print(apulista)
        print(int(apulista[-1])+1)

        k = 1
        i = 0
        j = 0
        while k < int(apulista[-1]) + 1:
            sana = sanat[i].strip(",.")
            pituus = len(sana)
            if pituus == k:
                j += 1
                i += 1
            else:
                if j != 0:
                    lista.append(j)
                lista.append(0)
                k += 1

        return lista

输出在这里:

    (venv) C:\python>testailua.py
    ['i', 'du', 'Om', 'Har', 'någon', 'tanken.', 'matematik.', 'inriktningsmöjligheten']
    [1, 2, 1, 1, 1, 1, 1]
    [1, 2, 2, 3, 5, 6, 9, 22]
    23
    Traceback (most recent call last):
      File "C:\python\testailua.py", line 54, in <module>
        print(sanamaarat(teksti))
      File "C:\python\testailua.py", line 28, in sanamaarat
        sana = sanat[i].strip(",.")
    IndexError: list index out of range

因此,我正在尝试在返回列表的正确索引中添加所需的零。但是 while 循环中有一些我看不到的逻辑错误。


预期结果为 [0,1,2,1,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1]

第一个“0”(索引零),因为长度为零的单词为零。第一个“1”(索引 1),因为有一个长度为 1 的单词。第一个“2”(索引 2),因为有两个长度为 2 的单词。等等。因此,每个索引都应该具有具有该索引长度的单词数。


@kederrac通过从集合导入 Counter 解决了这个问题。这是一个很好的答案,但我想知道如何使用循环以原始方式做到这一点,因为我仍然不知道我的循环中出了什么问题。

python list while循环 计数 索引错误

评论

0赞 jvkloc 3/7/2020
对不起。我不明白你评论的想法。最终目标是有一个列表,其中索引 0 的字数为零,索引 1 的字数为长度为 1,依此类推。
1赞 kederrac 3/7/2020
@jonne_k 我通过聊天中的讨论完成了您的问题
0赞 jvkloc 3/7/2020
谢谢。我接受了并投了赞成票。我是Python(和编程)的新手,所以我没有比循环更好的主意了。我仍然想知道我的循环出了什么问题,艰难。因此,任何人都可以自由地修复循环版本。
0赞 Jongware 3/7/2020
哎呀——我简要提到的解决方案实际上是“解决”......有些东西不在你的问题中。继续,没有造成伤害。

答:

2赞 kederrac 3/7/2020 #1

如果修改循环以检查索引的值和变量的长度:whileisaant

print('saant lenght: ', len(sanat))
while k < int(apulista[-1]) + 1:
    print('i = ', i)
    sana = sanat[i].strip(",.")
    pituus = len(sana)
    if pituus == k:
        j += 1
        i += 1
    else:
        if j != 0:
            lista.append(j)
        lista.append(0)
        k += 1

输出:

saant lenght:  8
i =  0
i =  1
i =  1
i =  2
i =  3
i =  3
i =  4
i =  4
i =  4
i =  5
i =  5
i =  6
i =  6
i =  6
i =  6
i =  7
i =  7
i =  7
i =  7
i =  7
i =  7
i =  7
i =  7
i =  7
i =  7
i =  7
i =  7
i =  7
i =  7
i =  8

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-61-873709d80e77> in <module>
     41     return lista
     42 
---> 43 sanamaarat(teksti )

<ipython-input-61-873709d80e77> in sanamaarat(merkkijono)
     28     while k < int(apulista[-1]) + 1:
     29         print('i = ', i)
---> 30         sana = sanat[i].strip(",.")
     31         pituus = len(sana)
     32         if pituus == k:

IndexError: list index out of range

你会发现你正在尝试访问一个与你的列表长度具有相同值的索引,这是不可能的,所以你得到了saanatIndexError

您的列表长度为 8,因此您可以在索引 7 之前访问元素,但您可以看到,在值为 8 之前,这会导致您的问题saanatIndexErrori


为了解决你的问题,你可以用按长度找到单词的频率:collections.Counter

from collections import Counter

teksti = "Har du någon tanken. Om inriktningsmöjligheten i matematik."

def sanamaarat(merkkijono):
    count = Counter(map(len, merkkijono.split()))
    max_lenght = max(count)
    return [count.get(n, 0) for n in range(max_lenght + 1)]

print(sanamaarat(teksti))

输出:

[0, 1, 2, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]

评论

0赞 kederrac 3/7/2020
@jonne_k立即检查我的答案
0赞 kederrac 3/7/2020
你想用你的代码做什么?也许我能找到一个不错的解决方案
0赞 kederrac 3/7/2020
第一个 0 因为?第一个 1 因为?前 2 个因为?会很有帮助
0赞 jvkloc 3/7/2020
让我们在聊天中继续讨论
0赞 kederrac 3/7/2020
@jonne_k现在检查我的答案