kontrolliertes "randommäßiges" Sortieren einer Lis

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.
Chill-man
User
Beiträge: 24
Registriert: Dienstag 8. Januar 2008, 10:46

kontrolliertes "randommäßiges" Sortieren einer Lis

Beitragvon Chill-man » Dienstag 8. Januar 2008, 11:00

Hallo erstmal, ;)

der Titel hört sich ja recht komisch an, allerdings ist mir nichts besseres eingefallen.

ich suche nach einer einfachen möglichkeit eine definierte Liste (bestehend aus 0-19) kontrolliert zu mischen, sodass man die verteilung sofort wiederherstellen könnte.

In Pascal würde das ungefair so aussehen:

Code: Alles auswählen


for i=0 to 19 do
begin
zz=random(19)
buffer = A[i]
A[i] = A[zz]
A[zz] = buffer
end




Code: Alles auswählen

import random
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
zz = random.randint(0,19)
print zz
buffer = l[i]
l[i] = l[zz]
l[zz] = buffer
print l



wie baue ich da eine for loop drum oder irgend eine andere loop?
Zuletzt geändert von Chill-man am Dienstag 8. Januar 2008, 14:29, insgesamt 1-mal geändert.
BlackJack

Beitragvon BlackJack » Dienstag 8. Januar 2008, 11:20

Habe ich etwas übersehen, oder suchst Du einfach nur `random.shuffle()`!?
Chill-man
User
Beiträge: 24
Registriert: Dienstag 8. Januar 2008, 10:46

Beitragvon Chill-man » Dienstag 8. Januar 2008, 14:30

schon ok hab selbst nen bissl rumprobiert

Code: Alles auswählen


import random

liste = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
r = []

i = 0
while i < 20:
    zz = random.randint(0,19)
    buffer = liste[i]
    liste[i] = liste[zz]
    liste[zz] = buffer
    r.append(zz+1)
    i = i+1

i = 0
while i < 20:
    if liste[i] == 1 or liste[i] == 5 or liste[i] == 9 or liste[i] == 13 or liste[i] == 17:
        print "Bed_1"
    if liste[i] == 2 or liste[i] == 6 or liste[i] == 10 or liste[i] == 14 or liste[i] == 18:
        print "Bed_2"
    if liste[i] == 3 or liste[i] == 7 or liste[i] == 11 or liste[i] == 15 or liste[i] == 19:
        print "Bed_3"
    if liste[i] == 4 or liste[i] == 8 or liste[i] == 12 or liste[i] == 16 or liste[i] == 20:
        print "Bed_4"
    if i == 19:
        randomnumbers = r
        final = liste
        print liste
    #ganz am Schluss
    i = i+1

CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Beitragvon CM » Dienstag 8. Januar 2008, 14:36

Was Du genau willst habe ich immer noch nicht kapiert. Und auch nicht, was die zweite Schleife bezweckt, aber den ersten Teil kannst Du abkürzen, wie von BlackJack angeregt:

Code: Alles auswählen

liste = range(1,21)
random.shuffle(liste)


Gruß,
Christian
Chill-man
User
Beiträge: 24
Registriert: Dienstag 8. Januar 2008, 10:46

Beitragvon Chill-man » Dienstag 8. Januar 2008, 15:21

hallo,

aber wenn ich das mit dem random.shuffle(liste) Befehl mache, dann kann ich das an einem späteren Zeitpunkt nicht mehr genau so generieren, oder gibts dafür auch einen shuffle code oder ka was?
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Beitragvon nkoehring » Dienstag 8. Januar 2008, 15:26

Hi Chill-man,

was meinst du mit "genau so generieren"? Du generierst doch eh mit Zufallswerten. Wo ist der unterschied, ob eine fertige Liste nun geshufflet (also durcheinandergewuerfelt) wird oder eben auf deine Art zufaellig erzeugt wird?

Oder ist es dir wichtig, dass auch doppelte Eintraege moeglich sind? Denn das passiert bei deiner Variante immermal... bei der anderen nicht!
BlackJack

Beitragvon BlackJack » Dienstag 8. Januar 2008, 15:27

`randomnumbers`, `r`, und `final` werden gar nicht benutzt.

Und da Du Pascal erwähntest weiss ich nicht ob die Zuweisungen an `randomnumbers` und `final` das machen was Du erwartest. In Pascal würden dabei Daten kopiert, in Python einfach nur die beiden Namen zusätzlich an die Objekte gebunden.

Bei Schleifen bei denen man weiss wie oft sie durchlaufen werden nimmt man keine ``while``-Schleife sondern eine ``for``-Schleife. Wenn man diese komischen letzten ``if``-Abfrage nach ``i == 19`` weg lässt und die Liste einfach nach der Schleife ausgibt, dann braucht man auch keinen Index `i` sondern kann direkt über die Zahlen iterieren. Dann werden die ``if``-Abfragen auch kürzer weil man nicht ständig ``liste[i]`` schreiben muss. Das lässt sich noch etwas weiter kürzen wenn man nicht mit Vergleichen und ``or`` arbeitet, sondern mit ``in``::

Code: Alles auswählen

        if i in (1, 5, 9, 13, 17):
            print "Bed_1"


Letztlich braucht man die ganzen ``if``\s aber nicht, weil sich die 'Bed_'-Nummer einfach berechnen lässt. Damit schrumpft der Quelltext auf folgendes::

Code: Alles auswählen

import random

def main():
    liste = range(1, 21)
    random.shuffle(liste)
   
    for i in liste:
        print 'Bed_%d' % ((i - 1) % 4 + 1)
    print liste

if __name__ == '__main__':
    main()



PS: Was meinst Du mit "an einem späteren Zeitpunkt nicht mehr genau so generieren!?
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Re: kontrolliertes "randommäßiges" Sortieren einer

Beitragvon schlangenbeschwörer » Dienstag 8. Januar 2008, 15:38

Noch ein Versuch :D
Chill-man hat geschrieben:sodass man die verteilung sofort wiederherstellen könnte.

Meinst du innerhalb der Laufzeit oder soll die Zufallsliste bei jedem Programmstart gleich sein?
Dazu könntest du entweder den gleichen Initialisierungswert verwenden, oder einen zufälligen, den du jedoch zur Laufzeit speicherst, oder du schreibst die Indices vom Anfang mit in deine Datenstruktur. Letzteres sähe dann in etwa so aus:
[(wert, zufallsindex), (wert, zufallsindex), ...]
Du musst einen Code dann anpassen und kannst die Liste sehr einfach in den Anfangszustand zurücksetzen.
(Du könntest natürlich auch einfach eine Kopie speichern.)

Nochwas zu deinem 2. Quelltext. Verstehen tue ich ihn auch net, aber

Code: Alles auswählen

if liste[i] == 1 or liste[i] == 5 or liste[i] == 9 or liste[i] == 13 or liste[i] == 17:

kannst du einfacher schreiben:

Code: Alles auswählen

if liste[i]  in (1, 5, 9, 13, 17):
Chill-man
User
Beiträge: 24
Registriert: Dienstag 8. Januar 2008, 10:46

Beitragvon Chill-man » Dienstag 8. Januar 2008, 15:43

Ui, das geht ja richtig flott hier ;)

also das mit dem zusammenfassen ist ja klasse (ich glaube man merkt, dass ich noch nicht so geübt in python bin), vielen Dank dafür schonmal.

Also mit dem genau so generieren meine ich, dass die die geshuffelte zahlenreihenfolge genau so nocheinmal erstellen möchte, ohne dass ich eine millionen mal rumprobieren möchte, damit genau die Zahlenfolge wieder kommt.

Achja ich hätte da noch eine Frage: kann man diese Liste irgendwie ausserhalb des scripts speichern um dann bei einem Neustart des scripts drauf zugreifen zu können?

Wofür brauche ich das ganze? ;)
Ich möchte einen Versuch mit Blender erstellen, bei dem 4 Objekte angezeigt werden, welche per Zufall ausgewählt werden sollen und verschoben werden sollen. Insgesamt soll dies 20 mal geschehen.
Das projekt ist soweit fertig, bis auf das mit dem random auswählen halt.

Danke schonmal Tillmann
Zuletzt geändert von Chill-man am Dienstag 8. Januar 2008, 15:52, insgesamt 1-mal geändert.
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Beitragvon Zap » Dienstag 8. Januar 2008, 15:50

Wenn du gerne bestimmte Konstelationen prüfen möchtest dann kannst du sie ja entweder als Parameter an dein Skript übergeben oder wie du schon überlegt hast aus einer Datei auslesen.
Was das Speichern angeht hat der Gerold mal eine nette Sammlung geschrieben:
http://www.python-forum.de/topic-6157.h ... +schreiben
Zuletzt geändert von Zap am Dienstag 8. Januar 2008, 15:51, insgesamt 1-mal geändert.
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Beitragvon schlangenbeschwörer » Dienstag 8. Januar 2008, 15:51

Wann willst du sie nochmal so erstellen? Beim nächsten Programmstart? Willst du sie dazu speichern?
Du kannst natürlich eine Liste speichern, da gibts etliche Möglichkeiten: txt, ini, pickle, ..., db. Wenn du aber nur eine Liste speichern willst, die du nur ausliest und nicht änderst, kannst du sie doch in deinen Quelltext schreiben, oder?
Chill-man
User
Beiträge: 24
Registriert: Dienstag 8. Januar 2008, 10:46

Beitragvon Chill-man » Dienstag 8. Januar 2008, 16:07

Danke Zap und schlangenbeschwörer.
Also die Liste möchte ich beim nächsten programmstart nochmal laden können, da mein script des öfteren neu geladen wird, allerdings der Versuch dann noch nicht fertig ist.

Zu dem generieren nochmal, der Versuch soll etliche Personen umfassen und da ich die Versuchspersonen einfach vor den Rechner setzten will und nicht die Konstellation vor jeder neuen Versuchsperson per Hand ändern möchte, soll sie random sein. Die Daten werden während des Versuchs in einer Datei abgespeichert da soll dann auch drin stehn wie diese gemischte Liste erzeugt wurde, sprich nicht einfach nur die endgültige Liste (die speicher ich sowieso ab).

Ich denke mal ich versuchs mit der pickle Methode.
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Beitragvon nkoehring » Dienstag 8. Januar 2008, 16:35

Du willst speichern wie die Liste erzeugt wurde??? Wie meinst du das denn nun wieder?
Chill-man
User
Beiträge: 24
Registriert: Dienstag 8. Januar 2008, 10:46

Beitragvon Chill-man » Dienstag 8. Januar 2008, 16:39

also ich will jede zahl die durch random.randint(0,19) erzeugt wurde mit dem dazugehörigen i (i=Trialnumber) speichern.
Es sei denn, es gibt bei dem random.shuffle befehl auch eine möglichkeit einfach nur zum beispiel

random.shuffle()#da sollte jetzt irgendwie ne id hinzukommen
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Beitragvon CM » Dienstag 8. Januar 2008, 16:41

Ich könnte ja noch verstehen, wenn Du noch die ursprüngliche Liste zu irgendeinem Zweck in der Hinterhand behalten möchtest, aber ansonsten .... genauso ratlos wie nkoehring.

Wenn Du auch den Eindruck hast, wir reden hier aneinander vorbei, so versuche doch mal in einfachen Worten das Problem zu beschreiben, das Du lösen willst - ohne Rücksicht auf programmiertechnische Details.

Gruß,
Christian

Wer ist online?

Mitglieder in diesem Forum: brainstir, Yahoo [Bot]