Erzeugte Liste enthält None-Objekt, warum?

Code-Stücke können hier veröffentlicht werden.
Antworten
Welpe
User
Beiträge: 26
Registriert: Mittwoch 30. Dezember 2020, 10:39

Moin,

ich möchte eine Liste mit zufälligen Einträgen erzeugen um eine Karte für ein Spiel zu erzeugen. Das funktioniert auch recht gut, allerdings bekomme ich unregelmäßig None Einträge in die Liste und das Programm stürzt ab. Kann mir vielleicht jemand sagen warum dieses None erzeugt wird oder was ich ändern sollte damit das nicht passiert?

Code: Alles auswählen

import random

def gen_random():
        rand = random.randint(0, 4)
        if rand == 0:
            return []
        if rand == 1:
            return ['Ork']
        if rand == 2:
            return ['Goblin']
        if rand == 3:
            return ['Goblin', 'Goblin', 'Ork']

def map(width, height):
    state = []
    for i in range(width):
        fields = []
        for j in range(height):
            fields.append(gen_random())
        state.append(fields)
    # print für fehlersuche
    for i in state:
        print(i)

map(5, 5)
Als Ausgabe erhalte ich dann:

Code: Alles auswählen

[['Goblin', 'Goblin', 'Ork'], [], ['Goblin', 'Goblin', 'Ork'], None, []]
[None, [], None, ['Goblin'], []]
[['Goblin', 'Goblin', 'Ork'], None, None, ['Goblin', 'Goblin', 'Ork'], None]
[['Goblin', 'Goblin', 'Ork'], ['Goblin', 'Goblin', 'Ork'], ['Goblin', 'Goblin', 'Ork'], ['Ork'], ['Ork']]
[[], ['Ork'], ['Goblin', 'Goblin', 'Ork'], ['Goblin', 'Goblin', 'Ork'], ['Goblin']]
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Bei randint ist der obere Wert inklusive, rand kann also auch den Wert 4 annehmen. Da kommt das None her.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Das ist ein Grund, warum man magischen Zahlen beim Programmieren vermeiden sollte. Hier kann man diese ganz einfach durch random.choice ersetzen:

Code: Alles auswählen

import random

FIELD_CHOICES = [
    [],
    ['Ork'],
    ['Goblin'],
    ['Goblin', 'Goblin', 'Ork'],
]

def generate_map(width, height):
    state = []
    for i in range(width):
        fields = []
        for j in range(height):
            fields.append(random.choice(FIELD_CHOICES))
        state.append(fields)

for row in generate_map(5, 5):
    print(row)
`map` ist der Name einer eingebauten Funktion und sollte nicht überschrieben werden.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Sieht auch nach einem sinnvollen Fall für „list comprehension“ aus:

Code: Alles auswählen

#!/usr/bin/env python3
import random

FIELD_CHOICES = [[], ["Ork"], ["Goblin"], ["Goblin", "Goblin", "Ork"]]


def generate_map(width, height):
    return [
        [random.choice(FIELD_CHOICES) for _ in range(height)]
        for _ in range(width)
    ]


def main():
    for row in generate_map(5, 5):
        print(row)


if __name__ == "__main__":
    main()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Welpe
User
Beiträge: 26
Registriert: Mittwoch 30. Dezember 2020, 10:39

kbr hat geschrieben: Montag 16. August 2021, 16:26 Bei randint ist der obere Wert inklusive, rand kann also auch den Wert 4 annehmen. Da kommt das None her.
Da liegt also der Hase im Pfeffer. Ich danke Dir für die schnelle Hilfe.

@Sirius3
Danke für Deine Anregung. Werde das nun auf random.choice umstellen, ist anscheinend auch weniger Fehleranfällig wenn ich die Felder mal erweitern möchte.
Antworten