【问题标题】:local variable optimization in python methodpython方法中的局部变量优化
【发布时间】:2014-05-20 11:14:38
【问题描述】:

在下面的代码中,我想知道是否会在每次调用方法时创建grade_to_score字典?

def get_score(grade):
    grade_to_score = {'A': 10, 'B': 8, 'C': 6, 'D': 4, 'F': 0} # step 1
    return grade_to_score.get(grade, -1)

另外,有什么方法可以确认?我正在使用 Python 2.7

【问题讨论】:

    标签: python python-2.7 optimization methods python-internals


    【解决方案1】:

    是的,它会的。要绕过它,您可以将它作为默认参数传递,这样它只会被评估一次:

    def get_score(grade, grade_to_score = {'A': 10, 'B': 8, 'C': 6, 'D': 4, 'F': 0}):
        return grade_to_score.get(grade, -1)
    

    或更好的方法:

    def get_score(grade, grade_to_score = None):
        if grade_to_score == None:
            grade_to_score = {'A': 10, 'B': 8, 'C': 6, 'D': 4, 'F': 0}
        return grade_to_score.get(grade, -1)
    

    【讨论】:

      【解决方案2】:

      要回答你的问题“有什么方法可以确认?”,你可以检查每次是否使用相同的对象:

      def get_score(grade):
          grade_to_score = {'A': 10, 'B': 8, 'C': 6, 'D': 4, 'F': 0} # step 1
          print(id(grade_to_score)) # check object ID
          return grade_to_score.get(grade, -1)
      

      现在你可以调用它了:

      >>> a = get_score("")
      50252080
      >>> b = get_score("")
      50249920
      >>> c = get_score("")
      50249776
      

      不同的id 意味着不同的对象,因此grade_to_score 显然正在在每次调用时重新创建。有趣的是,如果您在 for 循环中调用,则不会发生这种情况:

      >>> for _ in range(3):
          a = get_score("")
      
      50249920
      50249920
      50249920
      >>> scores = [get_score(grade) for grade in "ABC"]
      53737032
      53737032
      53737032
      

      【讨论】:

      • 你最后的代码 sn-p 很有趣......我仍然对这种行为一无所知
      • @johnsharpe 我尝试了你的第一个代码 sn-p。我在每次通话中都得到相同的 id。 :( 可能 id 不是正确的方法,因为即使分配给它的内容发生更改,局部变量也将始终具有相同的位置?
      • @comiventor 不,这不是 Python 变量/内存管理的工作方式
      • 你可能是对的,但我仍然不清楚第二个代码 sn-p 行为背后的原因
      • @comiventor 我也没有,坦率地说 - 这不是我所期望的。
      【解决方案3】:

      是的,每次调用函数时都会重新创建字典。

      您可以改为将其设为全局,或将其设为默认函数:

      grade_to_score = {'A': 10, 'B': 8, 'C': 6, 'D': 4, 'F': 0} # step 1
      
      
      def get_score(grade):
          return grade_to_score.get(grade, -1)
      

      def get_score(grade, grade_to_score={'A': 10, 'B': 8, 'C': 6, 'D': 4, 'F': 0}):
          return grade_to_score.get(grade, -1)
      

      在第二种情况下,grade_to_score 作为本地函数传递给函数,因此查找(略微)更快。

      在这两种情况下,字典文字都会在模块导入时执行一次。请注意,在这两种情况下,因为grade_to_score 是一个可变字典,所以您对其所做的任何更改都是全局的,而不是get_score() 调用的本地。

      【讨论】:

      • 你的第二个代码 sn-p 不是更好,因为局部变量查找比全局或内置变量查找快得多吗?
      • @comiventor:是的,这就是为什么它经常被这样使用。
      • @comiventor:抱歉,您只能将一个答案标记为已接受!很高兴我和 sshashank124 都有帮助。 :-)
      • 对不起@Martjin-Pieters 我也处于两难境地,我选择了 ssashank124,因为我首先看到了他的回答
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-23
      • 1970-01-01
      相关资源
      最近更新 更多