zufälliges Element aus mehrdimensionaler Liste auswählen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
martinprob
User
Beiträge: 2
Registriert: Freitag 8. November 2019, 19:07

ich möchte aus der Liste

liste= [[ 0 , 0 , 2 , 3 ] , [ 4 , 5 , 6 , 7 ] , [ 8 , 9 , 10 , 0 ] , [ 12 , 13 , 14 , 15 ]]

ein zufälliges Element mit dem Wert null auswählen und dessen Wert auf 12 ändern.
Kann mir jemand dabei helfen?

danke
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Was hast du schon versucht? Wo kommst du konkret nicht weiter?
Ein komplexes Problem teilt man in kleine Probleme und diese weiter, bis es eine triviale Lösung gibt. Bei dir also finden der Positionen mit 0 und dann einer zufällig davon auswählen (random.choice).
Zuletzt geändert von Sirius3 am Sonntag 19. Juli 2020, 17:18, insgesamt 1-mal geändert.
martinprob
User
Beiträge: 2
Registriert: Freitag 8. November 2019, 19:07

naechst = random.choice(liste)
naechstes_element = random.choice(naechst)

print(naechstes_element)

Leider bekomme ich damit nur das Element ausgegeben und nicht den Index, den würde ich brauchen
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Das sucht dir vielleicht ein zufälliges Element, aber kein zufälliges Element mit dem Wert 0.
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Zuerst musst du eine Liste bilden in der von allen Nullen die Indizes stehen. Dafür eignet sich eine Liste mit Tupeln.

Code: Alles auswählen

indizes_nullen = [(index_unterliste, index_nummer) for index_unterliste, unterliste in enumerate(nummern) for index_nummer, nummer in enumerate(unterliste) if nummer == 0]
Dann hast du eine Liste die so aussieht:

Code: Alles auswählen

[(0, 0), (0, 1), (2, 3)]
Aus dieser Liste kannst du dir dann mit random.choice() ein zufälligen Tupel ausgeben lassen und auch direkt wieder aufteilen:

Code: Alles auswählen

index_unterliste, index_nummer = random.choice(indizes_nullen)
Dann kannst du den Wert auch abändern:

Code: Alles auswählen

nummern[index_unterliste][index_nummer] = 12
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Just for fun.

Code: Alles auswählen

#!/usr/bin/env python3
import random

from glom import assign, Check, glom, Iter, Path, S, T, SKIP


def main():
    data = [[0, 0, 2, 3], [4, 5, 6, 7], [8, 9, 10, 0], [12, 13, 14, 15]]
    
    path_to_random_zero_spec = (
        [[{"path": S[Path], "value": T}]],
        Iter()
        .flatten()
        .filter(Check("value", equal_to=0, default=SKIP))
        .map("path")
        .all(),
        random.choice,
    )
    
    assign(data, Path(*glom(data, path_to_random_zero_spec)), 12)
    
    print(data)


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
DeaD_EyE
User
Beiträge: 1240
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Iterativ mit beliebiger Verschachtelung:

Code: Alles auswählen

import random
from collections.abc import Iterable


def random_choice_mat(matrix):
    is_iterable = lambda x: isinstance(x, Iterable)
    is_text = lambda x: isinstance(x, (str, bytes))
    while is_iterable(matrix) and not is_text(matrix):
        matrix = random.choice(matrix)
    return matrix
str und bytes brauchen eine spezielle Behandlung, da diese immer iterierbar sind, selbst wenn es nur ein Zeichen ist.
str und bytes sind Sequenzen.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@DeaD_EyE: Der `Iterable`-Test ist falsch, denn `random.choice` braucht kein `Iterable` sondern eine `Sequence`. Und `bytes` besonders zu behandeln ist auch nicht richtig, denn ein Indexzugriff liefert eine ganze Zahl und kein weiteres `bytes`-Objekt. Ebenso das iterieren über ein `bytes`-Objekt. Im Gegensatz zu `str`, wo beim Indexzugriff und iterieren wieder `str` geliefert wird.

So Test ist letztlich auch immer unsicher, weil es durchaus Werte geben kann die zwar den `isinstance()`-Test nicht bestehen, aber trotzdem mit `random.choice()` funktionieren. Andererseits kann es Sequenztypen geben in die nicht weiter ”abgetaucht” werden soll, sondern die als Ergebnis in Frage kommen. Typprüfungen sind fast immer unschön.

Es passt auch nicht wirklich zur Aufgabenstellung. Da soll eine zufällig ausgewählte 0 durch einen anderen Wert ersetzt werden.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten