Python list ein random element ausgeben?

4 Antworten

Die bisherigen Ansätze gefallen mir nicht soooo gut, weil die Liste mit den ursprünglichen Objekten eigentlich unveränderlich sein sollte.

Ich würde eine neue Liste mit allen Offsets der Elemente in der Urpsürnglichen Liste anlegen, diese verwürfeln, und dann einfach darüber iterieren.

Damit ersparst du dir jegliches hin- und her kopieren von Objekten, und Doubletten sind ohne weitere Prüfungen komplett ausgeschlossen.

Klingt komplizierter, als es ist! Als Code sieht das einfach so aus:

from random import shuffle

words = ['foo', 'bar', 'baz', 'qux']

offsets = list(range(len(words)))
shuffle(words)

for i in offset:
  word = words[i]

  print(word)

Das gibt dir die ursprüngliche Liste in zufälliger Reihenfolge ohne Doubletten aus, und lässt dabei dir ursprüngliche Liste komplett unangetastet, sodass du sie später weiter nutzen kannst.

Viel Spaß! :)

Woher ich das weiß:Berufserfahrung
alfredo153  01.10.2020, 06:42
offsets = list(range(len(words)))

Falls wieder mal jemand fragt, warum bei range(n) von 0 bis vor n rauskommt, ist das eine schöne Demonstration :)

1
alfredo153  01.10.2020, 07:13

Wobei man argumentieren kann, dass eine Kopie der Liste auch nicht mehr kostet - es werden sowieso nur Referenzen kopiert, keine Werte. Die etwas kürzere/intuitivere Variante sollte also genauso effizient sein:

from random import shuffle

words = ['foo', 'bar', 'baz', 'qux']

shuffled = words.copy()
shuffle(shuffled)

for word in shuffled:
  print(word)
1
TinaAusWien  01.10.2020, 07:19
@alfredo153

OK, in dem Falle hast du natürlich Recht. Eine Deepcopy ist ja nicht nötig. :)

1
KarlRanseierIII  01.10.2020, 17:25

Hast es einen tieferen Sinn, nachdem Du den inplace Shuffle auf words gemacht hast nochmal eine Indexliste anzulegen?

Ich meine, warum nicht:

shuffle(words)
for word in words:
    print (word)

Oder wolltest Du die Ursprungsliste unverändert lassen?

offsets=list(range(len(words)))
shuffle(offsets)
for offset in offsets:
   print(words[i])

Es gibt noch eien elegante pythonische Variante:

def make_shuffled(l):
    shuffle(l)
    for v in l:
       yizld l

Mit:

mylist=[......]
shuffled=make_shuffled(mylist)
for val in shuffled: # Oder jede andere Nutzungsart
     print(val)

Kann ich mir ein ranodmisierten Generator instanziieren, den ich als "Arbeitskopie" nutzen kann.

1
TinaAusWien  01.10.2020, 17:28
@KarlRanseierIII

Der Fragensteller will die ursprünglich Liste danach weiter verwendeny deshalb der Umweg mit den Indizes.

1
KarlRanseierIII  01.10.2020, 17:29
@TinaAusWien

Ja, nur hast DU die Urpsrubngsliste geshufflet, nicht die Indices - deswegen war ich verwirrt.

1
TinaAusWien  01.10.2020, 17:31
@KarlRanseierIII

Das war dann wohl geistige Verwirrtheit! So war das natürlich nicht geplant. Danke türs Fehlerfinden! :)

1
liste = a,b,c,d,..
savelist=[ ]
for i in random(liste):
  if i not in savelist:
    savelist=savelist+i

so ähnlich, einfach eine zusätzliche liste erstellen und alle zufällig ausgewählten objecte in die liste einfügen.

bei der ramdom abfrage, abfragen ob es bereits in der liste ist.

wenn es noch nicht in der liste ist, dann halt in die liste einfügen. so wird keins doppelt gewählt

den genauen syntax weis ich grad nicht genau. hab ne weile nicht mit python gearbeitet

einfachste Variante:

Wähle zufälliges Element und entferne es daraufhin.

Somit kann es nicht erneut ausgewählt werden.

Yasuo09 
Fragesteller
 01.10.2020, 01:46

Aber sollte nicht gelöscht werden da nochmal verwendet werden muss

0
KarlRanseierIII  01.10.2020, 01:49
@Yasuo09

Dann lege eien Kopie an und arbeite auf der, oder verschiebe die rausgezogenen Elemente in eine andere Liste.

Oder füge das Elemente hinten an nach dem Entfernen udn verküze den Abschnitt auf dem randomisiert wird.

Oder, oder, oder....

1
from random import choice
print(choice([1,2,3,4]))

Edit:

from random import randint
l = [1,2,3,4]
i = randint(0,len(l)-1)
print(l.pop(i))
DeiDei2303  01.10.2020, 01:42

Ahh, hubs. Man könnte was gewählte dann poppen

0