简体   繁体   English

在Python中使用Dictionaries代替Case / Switch语句

[英]Using Dictionaries in Python in place of Case/Switch statement

I want to randomize a rubik's cube that is initialized as complete (all colors on the correct sides). 我想随机化一个初始化为完整的rubik立方体(正确边上的所有颜色)。 I have move functions that rotate the cube. 我有移动旋转立方体的函数。 I want to randomly pick 50 functions in a row to properly randomize it. 我想连续随机选择50个函数来正确随机化它。

I am doing this project to learn a little bit more about Python, since I mostly do C++ and I see there is no case/switch for Python, so I am trying a dictionary. 我正在做这个项目来学习更多关于Python的知识,因为我主要做C ++而且我看到Python没有case / switch,所以我正在尝试一本字典。 When I make the dictionary, the code seems to execute for some reason: 当我创建字典时,代码似乎由于某种原因而执行:

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]

So when I make this dictionary, it seems to run through and execute all 11 entries for some reason (I think). 因此,当我创建这个字典时,由于某种原因(我认为)它似乎贯穿并执行所有11个条目。 I can't seem to find a better way, at least more elegant than a long if/elif string of statements. 我似乎无法找到更好的方法,至少比if / elif长语句更优雅。

!EDIT: Implementing both suggestions, the ("inverted") flag for the functions are not being set by either suggestion. !编辑:实现这两个建议,任何建议都没有设置函数的(“倒”)标志。 For example, calling 1 and 7 both give me down_turn, but the output shows that the flag was not set when it should have been on number 7. 例如,调用1和7都会给我down_turn,但是输出显示标志在它应该在7号时没有设置。

Any ideas? 有任何想法吗?

When you define the dict, it's actually calling the functions, and storing the return value in the dictionary. 当你定义dict时,它实际上调用了函数,并将返回值存储在字典中。 To just have the dictionary store a reference to the functions, you need to drop the trailing parentheses. 要让字典存储对函数的引用,您需要删除尾随括号。 So something like: 所以类似于:

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

Then, at the bottom, call scramble[i]() . 然后,在底部,调用scramble[i]()

This will call the function with no arguments. 这将调用没有参数的函数。 To handle the case where you pass "inverted" as an argument, you could either define separate functions like up_turn_inverted(), etc., or you could have the dictionary store a 2-ple consisting of the function, and the argument, then call something liks scramble[i][0](scramble[i][1]) 要处理将“反向”作为参数传递的情况,您可以定义单独的函数,如up_turn_inverted()等,或者您可以让字典存储由函数和参数组成的2-ple,然后调用有些人喜欢scramble[i][0](scramble[i][1])

Update from suggestion in comments: You could also use lambda expressions to define the functions, particularly the ones that require an argument. 从注释中的建议更新:您还可以使用lambda表达式来定义函数,尤其是需要参数的函数。 This is basically equivalent to defining an up_turn_inverted function, but done in-place as an anonymous function. 这基本上等同于定义up_turn_inverted函数,但作为匿名函数就地完成。 It would look like this: 它看起来像这样:

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

etc. 等等

I believe this is called "functions as first-class values", implying most importantly that you can pass identifiers referring to functions as parameters to other functions. 我相信这被称为“函数作为一等值”,这意味着最重要的是你可以将参考函数的标识符作为参数传递给其他函数。

When you define your dictionary, the Python interpreter evaluates the functions and stores the values in the dictionary. 定义字典时,Python解释器会评估函数并将值存储在字典中。 To put this off until you generate your random numbers, try instead storing references to the functions themselves in your dictionary, by leaving off the parentheses: 要在生成随机数之前将其关闭,请尝试通过省略括号来存储对字典中函数本身的引用:

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
                }

Then when calling your functions in the for loop you'll have to distinguish between your normal and inverted cases by which parameters you pass: 然后在for循环中调用函数时,您必须区分正常情况和反向情况,通过这些情况传递的参数:

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

or more simply: 或更简单地说:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM