Python3: IndexError: list index out of range

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Bart1201
  • Registratie: Augustus 2014
  • Niet online
Ik heb een python script gemaakt om de gegevens uit een csv bestand te verwerken:

Python: aanmaningen
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
__author__ = 'Bart'

import csv

f = open('H:/aanmaningen.chr', 'r')
reader = csv.reader(f, delimiter=';')


def read_cell(x, y):
    y_count = 0
    for n in reader:
        if y_count == y:
            cell = n[x]
            print(cell + "  (cell)")
            return cell
        y_count += 1


def read():
    for i, row in enumerate(reader):
        i11 = int(i) + 11
        i4 = int(i) - 4
        i3 = int(i) - 3
        i2 = int(i) - 2
        iplus1 = int(i) + 1
        imin1 = int(i) - 1
        if len(row) == 82:
            if read_cell(72, i) == 'Totaal' and read_cell(74, i) != read_cell(74, i11):
                ernst = read_cell(3, i)
                debnr = read_cell(28, imin1)
                naam = read_cell(0, i4)
                straat = read_cell(0, i2)
                plaats = read_cell(0, imin1)
                kvk = read_cell(46, iplus1)
                iban = read_cell(73, iplus1)
                bic = read_cell(67, iplus1)
                print(straat)
            else:
                print('else')
    return


def write(ernst, vve, adminnr, debnr, naam, straat, plaats, totaal, kvk, iban, bic):
    return

read()

f.close()


maar ik krijg de volgende error:

C:\Python34\python.exe C:/Users/Bart/PycharmProjects/Aanmaningen/aanmaningen.py
Traceback (most recent call last):
  File "C:/Users/Bart/PycharmProjects/Aanmaningen/aanmaningen.py", line 45, in <module>
    read()
  File "C:/Users/Bart/PycharmProjects/Aanmaningen/aanmaningen.py", line 31, in read
    straat = read_cell(0, i2)
  File "C:/Users/Bart/PycharmProjects/Aanmaningen/aanmaningen.py", line 13, in read_cell
    cell = n[x]
IndexError: list index out of range

Process finished with exit code 1


En ik heb geen idee wat er aan de hand is... 8)7

Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Wat er aan de hand is, is dat op deze regel:

Python:
1
straat = read_cell(0, i2)


de waarde voor i2 waarschijnlijk niet bestaat in datgene dat je in wilt lezen.

Acties:
  • 0 Henk 'm!

  • WernerL
  • Registratie: December 2006
  • Laatst online: 17:50
i2 staat gewoon stukje verder naar boven op regel 27.
code:
1
i2 = int(i) - 2


De error wordt veroorzaakt doordat x een niet-bestaande index is in 'n'. i2 de parameter voor y in de read_cell functie. ;)

In andere woorden, de input in het csv bestand is waarschijnlijk korter dan 73 tekens lang.

[ Voor 8% gewijzigd door WernerL op 24-07-2015 16:03 ]

Roses are red, violets are blue, unexpected '{' on line 32.


Acties:
  • 0 Henk 'm!

  • Kalua
  • Registratie: April 2009
  • Laatst online: 15:46
Je kan beter even de help pagina van de CSV reader class erbij pakken: https://docs.python.org/3/library/csv.html

enumarate heb je namelijk helemaal niet nodig namelijk. En als de file headers heeft is de DictReader nog makkelijker.

Acties:
  • 0 Henk 'm!

  • Bart1201
  • Registratie: Augustus 2014
  • Niet online
Ik heb de code ietwat veranderd:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import csv

f = open('H:/aanmaningen.chr', 'r')
reader = csv.reader(f, delimiter=';')


def read_cell(x, y):
    reader_list = list(reader)
    string = reader_list[y][x]
    return string


def read():
    for i, row in enumerate(reader):
        i11 = int(i) + 11
        i4 = int(i) - 4
        i3 = int(i) - 3
        i2 = int(i) - 2
        iplus1 = int(i) + 1
        imin1 = int(i) - 1
        if len(list(row)) == 82:
            if read_cell(72, i) == 'Totaal' and read_cell(74, i) != read_cell(74, i11):
                ernst = read_cell(3, i)
                debnr = read_cell(28, imin1)
                naam = read_cell(0, i4)
                straat = read_cell(0, i2)
                plaats = read_cell(0, imin1)
                kvk = read_cell(46, iplus1)
                iban = read_cell(73, iplus1)
                bic = read_cell(67, iplus1)
            else:
                print('else')
    return


def write(ernst, vve, adminnr, debnr, naam, straat, plaats, totaal, kvk, iban, bic):
    return

read()


f.close()


ik heb "if len(list(row)) >= 82:" zodat de code alleen maar draait wanneer de regel lang genoeg is. Echter, dit geeft nog steeds dezelfde fout.

voor mensen die de file willen inkijken, stuur ik m wel als PM door.

Acties:
  • 0 Henk 'm!

  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
Na je eerste for-loop heb je je reader helemaal uitgelezen. Je doet namelijk dit:

code:
1
2
3
4
5
6
7
8
for i, row in enumerate(reader):
  # de eerste regel van je csv-bestand is nu ingeladen
  # read_cell(72, i)
  reader_list = list(reader)
  # de rest van je csv-bestand is nu ook ingeladen
  # read_cell(74, i)
  reader_list = list(reader)
  # reader_list is nu leeg, want reader was al volledig uitgelezen



Wat mist in je verhaal is wat je precies probeert te doen. Moet je je steeds willekeurige cellen uit je bestand inlezen? Het zou helpen als je een voorbeeld van je bestandsformaat post (uiteraard hoef je daar niet de daadwerkelijke data voor te gebruiken).

Als je inderdaad willekeurig door je bestand wilt springen dan wil je het bestand in één ruk inlezen, dwz
code:
1
2
reader = csv.reader(f, delimiter=';')
data = list(reader)

waarna data een 2d-array met je hele bestand is.

Acties:
  • 0 Henk 'm!

  • Bart1201
  • Registratie: Augustus 2014
  • Niet online
Omdat het programma dat de data genereert een hoop lege rijen overlaat en dus ook niet consistent is met de data die ik nodig heb, het is de bedoeling dat ik met de persoonsgegevens die uitgelezen worden een aanmaning genereer om daarna naar de volgende persoon gaan mits dezelfde data er niet nog eens staat.
Het bestand is ook niet soms keer dezelfde lengte, omdat het gaat om een lijst van personen die een betalingsachterstand hebben. Daarom (is het idee) dat ik relatief vanuit de lijn met "totaal" de benodigde gegevens uitlees en een aanmaning genereer, om daarna door te gaan naar de volgende entry mits die niet van dezelfde persoon is. (Dat heeft te maken met hoe het boekhoudprogramma aanmaningen exporteert 8)7 )

Acties:
  • 0 Henk 'm!

  • BoringDay
  • Registratie: Maart 2009
  • Laatst online: 13-05 21:49
Bart1201 schreef op vrijdag 24 juli 2015 @ 18:29:
Omdat het programma dat de data genereert een hoop lege rijen overlaat en dus ook niet consistent is met de data die ik nodig heb, het is de bedoeling dat ik met de persoonsgegevens die uitgelezen worden een aanmaning genereer om daarna naar de volgende persoon gaan mits dezelfde data er niet nog eens staat.
Het bestand is ook niet soms keer dezelfde lengte, omdat het gaat om een lijst van personen die een betalingsachterstand hebben. Daarom (is het idee) dat ik relatief vanuit de lijn met "totaal" de benodigde gegevens uitlees en een aanmaning genereer, om daarna door te gaan naar de volgende entry mits die niet van dezelfde persoon is. (Dat heeft te maken met hoe het boekhoudprogramma aanmaningen exporteert 8)7 )
Als je onbekend bent met de opbouw van de export dan zou ik dat toch eerst in kaart brengen voordat je gaat programmeren.

Acties:
  • 0 Henk 'm!

  • Bart1201
  • Registratie: Augustus 2014
  • Niet online
na wat werk:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import csv

f = open('C:/Users/Bart/Documents/aanmaningen/aanmaningen.chr', 'r', newline='')
reader = csv.reader(f, delimiter=';')


output = open('C:/Users/Bart/Documents/aanmaningen/aanmaningen.csv', 'w', newline='')
writer = csv.writer(output)

for row in reader:
    if any(field.strip() for field in row):
        writer.writerow(row)

f.close()
output.close()

n = open('C:/Users/Bart/Documents/aanmaningen/aanmaningen.csv', 'r', newline='')
new = csv.reader(n)
list = list(new)


def read():
    for i, row in enumerate(list):
        if len(row) > 73:
            if row[72] == 'Totaal':
                ernst = row[3]
                debnr = row[28]
                naam1 = list[(i - 4)][0]
                naam2 = list[(i - 3)][0]
                naam = naam1 + naam2
                straat = list[(i - 2)][0]
                plaats = list[(i - 1)][0]
                totaal = row[74]
                kvk = list[(i + 1)][46]
                iban = list[i + 1][73]
                bic = list[i + 1][67]
                print(iban)
            else:
                print('elsebottom')
        else:
            print('elsetop')


def write(ernst, vve, adminnr, debnr, naam, straat, plaats, totaal, kvk, iban, bic):
    return

read()


f.close()

Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Je laatste f.close() op regel 50 moet n.close() zijn. Daarop doorgaand is het beter om het with-statement te gebruiken:

Voorbeeld met een stukje van jouw code:

Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import csv

inFilename = 'C:/Users/Bart/Documents/aanmaningen/aanmaningen.chr'
outFilename = 'C:/Users/Bart/Documents/aanmaningen/aanmaningen.csv'

with open(inFilename, 'r', newline='') as f, open(outFilename, 'w', newline='') as output:
  reader = csv.reader(f, delimiter=';')
  writer = csv.writer(output)

  for row in reader:
    if any(field.strip() for field in row):
    writer.writerow(row)

# de close() aanroepen zijn nu overbodig

with open(outFilename, 'r', newline='') as n:
  new = csv.reader(n)
  list = list(new)


... et cetera ...


Op die manier hoef je geen close() meer aan te roepen en kun je die ook niet vergeten (of foutief gebruiken, zoals in je code).

[ Voor 3% gewijzigd door HuHu op 27-07-2015 12:42 ]


Acties:
  • 0 Henk 'm!

  • Bart1201
  • Registratie: Augustus 2014
  • Niet online
@HuHu

Ik ga mijn code zsm veranderen!

[ Voor 98% gewijzigd door Bart1201 op 27-07-2015 13:28 . Reden: 8)7 ]

Pagina: 1