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

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

我有一个函数可以计算每个长度的单词数,直到并包括任何给定文本中最长的单词。我陷入了困境。 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,1,0,0,0,0,0,0,0,0,0,0,0 ,0,0,1]

第一个“0”(索引为零)因为有零个字的长度为零。第一个 '1'(到索引 1)因为有一个字的长度为 1。第一个 '2'(到索引 2)因为有两个长度为 2 的单词。等等。所以每个索引应该有具有该索引长度的单词数。


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

如果您修改 while 循环以检查索引的值 i 和变量的长度 saant:

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

您会发现您正在尝试访问与列表长度具有相同值的索引 saanat 这是不可能的,因此您得到了 IndexError

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


要解决您的问题,您可以使用 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]