Seite 1 von 1

Erzeugte Liste enthält None-Objekt, warum?

Verfasst: Montag 16. August 2021, 16:08
von Welpe
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']]

Re: Erzeugte Liste enthält None-Objekt, warum?

Verfasst: Montag 16. August 2021, 16:26
von kbr
Bei randint ist der obere Wert inklusive, rand kann also auch den Wert 4 annehmen. Da kommt das None her.

Re: Erzeugte Liste enthält None-Objekt, warum?

Verfasst: Montag 16. August 2021, 16:38
von Sirius3
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.

Re: Erzeugte Liste enthält None-Objekt, warum?

Verfasst: Montag 16. August 2021, 18:26
von __blackjack__
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()

Re: Erzeugte Liste enthält None-Objekt, warum?

Verfasst: Dienstag 17. August 2021, 07:42
von Welpe
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.