Seite 1 von 1
zufälliges Element aus mehrdimensionaler Liste auswählen
Verfasst: Sonntag 19. Juli 2020, 15:13
von martinprob
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
Re: zufälliges Element aus mehrdimensionaler Liste auswählen
Verfasst: Sonntag 19. Juli 2020, 17:16
von Sirius3
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).
Re: zufälliges Element aus mehrdimensionaler Liste auswählen
Verfasst: Sonntag 19. Juli 2020, 17:37
von martinprob
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
Re: zufälliges Element aus mehrdimensionaler Liste auswählen
Verfasst: Sonntag 19. Juli 2020, 17:57
von Sirius3
Das sucht dir vielleicht ein zufälliges Element, aber kein zufälliges Element mit dem Wert 0.
Re: zufälliges Element aus mehrdimensionaler Liste auswählen
Verfasst: Montag 20. Juli 2020, 06:55
von Jankie
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:
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:
Re: zufälliges Element aus mehrdimensionaler Liste auswählen
Verfasst: Montag 20. Juli 2020, 08:12
von __blackjack__
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()
Re: zufälliges Element aus mehrdimensionaler Liste auswählen
Verfasst: Montag 20. Juli 2020, 14:52
von DeaD_EyE
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.
Re: zufälliges Element aus mehrdimensionaler Liste auswählen
Verfasst: Montag 20. Juli 2020, 16:50
von __blackjack__
@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.