2012-04-29 3 views
8

Ich möchte einen Rubik-Würfel randomisieren, der als vollständig initialisiert ist (alle Farben auf der richtigen Seite). Ich habe Bewegungsfunktionen, die den Würfel drehen. Ich möchte nach dem Zufallsprinzip 50 Funktionen in einer Reihe auswählen, um sie richtig zu randomisieren.Verwenden von Dictionaries in Python anstelle der Case/Switch-Anweisung

Ich mache dieses Projekt, um ein wenig mehr über Python zu lernen, da ich meistens C++ mache und ich sehe, dass es keinen Fall/Schalter für Python gibt, also versuche ich ein Wörterbuch. Als ich das Wörterbuch zu machen, scheint der Code aus irgendeinem Grund auszuführen:

def random_cube(self): 
    scramble = { 0 : self.up_turn(), 
        1 : self.down_turn(), 
        2 : self.left_turn(), 
        3 : self.right_turn(), 
        4 : self.front_turn(), 
        5 : self.back_turn(), 
        6 : self.up_turn("inverted"), 
        7 : self.down_turn("inverted"), 
        8 : self.left_turn("inverted"), 
        9 : self.right_turn("inverted"), 
        10: self.front_turn("inverted"), 
        11: self.back_turn("inverted") 
       } 
    for x in range(50): 
     i = random.randint(0,11) 
     scramble[i] 

Also, wenn ich dieses Wörterbuch machen, es durch und führen Sie alle 11 Einträge aus irgendeinem Grund scheint zu laufen (glaube ich). Ich finde keinen besseren Weg, zumindest eleganter als eine lange Reihe von Aussagen.

! BEARBEITEN: Bei der Umsetzung beider Vorschläge wird das ("invertierte") Flag für die Funktionen nicht durch einen der beiden Vorschläge gesetzt. Zum Beispiel, rufen Sie 1 und 7 beide geben Sie down_turn, aber die Ausgabe zeigt, dass das Flag nicht gesetzt wurde, wenn es auf Nummer 7 hätte sein sollen.

Irgendwelche Ideen?

+1

Als Design-Note, es gibt wirklich nur zwei verschiedene sind unterwegs s kann man auf einem Zauberwürfel tun.Der Rest ist nur eine Frage der Ausrichtung der Gesichter. Es könnte einfacher sein, eine Funktion wie folgt zu schreiben: 'def rotate (face, clockWise = True):' Alternativ zur Verwendung einer dict- und 'for'-Schleife können Sie eine Liste erstellen und' random.choice' verwenden Wählen Sie daraus. –

+0

für die random.choice aus der Liste, habe ich auch daran gebastelt. Ich habe die Funktionsaufrufe in eine Liste eingefügt und das versucht, aber nicht ganz für mich funktioniert ... Außerdem habe ich den Würfel so aufgebaut, dass er immer weiß wie "vorne" ist. Ich denke nicht, dass das der beste Weg war, es darzustellen: \ –

Antwort

15

Wenn Sie das Diktat definieren, ruft es tatsächlich die Funktionen auf und speichert den Rückgabewert im Wörterbuch. Um nur einen Verweis auf die Funktionen im Wörterbuch speichern zu lassen, müssen Sie die abschließenden Klammern löschen. So etwas wie:

scramble = { 0: self.up_turn, 
       1: self.down_turn, 
       etc. 

Dann an der Unterseite, rufen scramble[i]().

Dies wird die Funktion ohne Argumente aufrufen. Um den Fall zu behandeln, in dem Sie "invertiert" als Argument übergeben, könnten Sie entweder separate Funktionen wie up_turn_inverted(), etc. definieren, oder Sie könnten im Dictionary einen 2-ple speichern, der aus der Funktion und dem Argument besteht, und dann aufrufen etwas liks scramble[i][0](scramble[i][1])

Update vom Vorschlag in den Kommentaren: Sie könnten auch Lambda-Ausdrücke verwenden, um die Funktionen zu definieren, insbesondere diejenigen, die ein Argument erfordern. Dies entspricht im Wesentlichen der Definition einer up_turn_inverted-Funktion, die jedoch als anonyme Funktion ausgeführt wird. Es würde wie folgt aussehen:

6: lambda: self.up_turn("inverted") 
7: lambda: self.down_turn("inverted") 

usw.

+3

Eine andere Möglichkeit wäre, 'lambda:' zu verwenden, um die invertierten Aufrufe zu erzeugen. – Amber

+0

Oder was ist mit einer Inline-Bedingung? d. h. 'scramble [i] (() wenn i <6 else (" invertiert ")) –

+1

Als ein generelles Prinzip erscheint das Annehmen von Annahmen über die Wörterbuchordnung als etwas, das möglichst vermieden werden sollte. Ich würde für die Lambda-Lösung stimmen. – happydave

2

Ich glaube, diese „Funktionen als erstklassige Werte“ genannt wird, was bedeutet, was am wichtigsten ist, dass Sie Identifikatoren Bezug auf Funktionen als Parameter an andere Funktionen übergeben können.

Wenn Sie Ihr Wörterbuch definieren, wertet der Python-Interpreter die Funktionen aus und speichert die Werte im Wörterbuch. Um dies zu setzen, bis Sie Ihre Zufallszahlen erzeugen, versuchen Sie stattdessen Verweise auf die Funktionen selbst in Ihrem Wörterbuch zu speichern, indem Sie die Klammern Weglassen:

def random_cube(self): 
    scramble = { 0 : self.up_turn, 
        1 : self.down_turn, 
        2 : self.left_turn, 
        3 : self.right_turn, 
        4 : self.front_turn, 
        5 : self.back_turn, 
        6 : self.up_turn, 
        7 : self.down_turn, 
        8 : self.left_turn, 
        9 : self.right_turn, 
        10: self.front_turn, 
        11: self.back_turn 
       } 

Dann, wenn Ihre Funktionen in der for-Schleife aufrufen Sie haben werde unterscheiden zwischen normalen und umgekehrten Fälle, mit denen Parameter übergeben Sie:

for x in range(50): 
     i = random.randint(0,11) 
     if i <= 5: 
      scramble[i]() 
     else: 
      scramble[i]("inverted") 

oder einfacher:

for x in range(50): 
     i = random.randint(0,11) 
     scramble[i](() if i < 6 else ("inverted")) 
+0

danke für die Antwort. Ich habe nicht daran gedacht, dass der Dolmetscher auswerten muss, um in den Wörterbuchwert zu kommen. –

Verwandte Themen