8

完全なものとして初期化されているルービックキューブをランダム化したい(すべての色が正しい側にある)。立方体を回転させる移動機能があります。適切にランダム化するために、連続して 50 個の関数をランダムに選択したいと考えています。

私は主に C++ を使用しており、Python のケース/スイッチがないことがわかっているため、Python についてもう少し学ぶためにこのプロジェクトを行っています。そのため、辞書を試しています。辞書を作成すると、何らかの理由でコードが実行されるようです。

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]

なので、この辞書を作ってみると、なぜか11項目全て実行してしまうようです(たぶん)。少なくとも if/elif ステートメントの長い文字列よりもエレガントな、より良い方法を見つけることができないようです。

!EDIT: 両方の提案を実装すると、関数の (「反転」) フラグはどちらの提案によっても設定されません。たとえば、1 と 7 を呼び出すと両方とも down_turn が返されますが、出力は、7 番にあるはずのフラグが設定されていないことを示しています。

何か案は?

4

2 に答える 2

16

dictを定義すると、実際には関数が呼び出され、戻り値が辞書に格納されます。辞書に関数への参照を保存させるには、末尾の括弧を削除する必要があります。だから次のようなもの:

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

次に、下部でを呼び出しますscramble[i]()

これにより、引数なしで関数が呼び出されます。「inverted」を引数として渡す場合を処理するには、up_turn_inverted()などの個別の関数を定義するか、関数と引数で構成される2つのpleを辞書に格納してから呼び出します。何か好きなものscramble[i][0](scramble[i][1])

コメントの提案からの更新:ラムダ式を使用して、関数、特に引数を必要とする関数を定義することもできます。これは基本的にup_turn_inverted関数を定義するのと同じですが、無名関数としてインプレースで実行されます。次のようになります。

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

于 2012-04-29T03:58:13.967 に答える
2

これは「ファーストクラスの値としての関数」と呼ばれ、最も重要なことは、関数をパラメーターとして参照する識別子を他の関数に渡すことができることを意味すると思います。

辞書を定義すると、Pythonインタープリターが関数を評価し、値を辞書に格納します。乱数を生成するまでこれを延期するには、代わりに、括弧を省略して、関数自体への参照を辞書に保存してみてください。

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
                }

次に、forループで関数を呼び出すときに、パラメーターを渡す通常の場合と逆の場合を区別する必要があります。

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

またはもっと簡単に:

    for x in range(50):
        i = random.randint(0,11)
        scramble[i]( () if i < 6 else ("inverted"))
于 2012-04-29T03:59:59.383 に答える