理解Python中的闭包范围

时间:2017-08-27 07:33:47

标签: python sorting scope closures

这是Bratt Slatkin的书中的例子

def sort_priority(values,   group):
    def helper(x):
        if  x   in  group:
            return  (0, x)
        return  (1, x)
    values.sort(key=helper)

此外,他们给出了这些值

numbers =   [8, 3,  1,  2,  5,  4,  7,  6]
group   =   {2, 3,  5,  7}
sort_priority(numbers,  group)
print(numbers)

我们有

[2, 3,  5,  7,  1,  4,  6,  8]

我不明白这个例子。为什么我们有两次返回以及辅助函数实际上做了什么?

4 个答案:

答案 0 :(得分:4)

您将该功能读作:

def helper(x):
    if x in group:
        return (0, x)
    else:
        return (1, x)

或者,更简洁,

def helper(x):
    return (x not in group, x)

这背后的直觉是sort接受在每个元素上调用的key回调。对于每个元素,调用helper返回一个元组(可以是(0, x)(1, x),具体取决于VIP列表中是否存在x

您应该了解元组是基于多个谓词排序的,这意味着在决定元素的顺序时会考虑元组中的两个项。这意味着,与返回(0, x)的{​​{1}}因为(1, x)相比,将首先对组返回0 < 1的元素进行排序。

在此之后,我们有两个组,第一个元素0和第一个元素1。所有0组元素都将首先出现,但这些元素的顺序取决于元组中的第二项 - x1组元素类似。

您的意见:

Group0: [2, 3, 5, 7]
Group1: [8, 1, 4, 6]

Ordering within Group0: [2, 3, 5, 7]
Ordering within Group1: [1, 4, 6, 8]

Overall ordering: [Group0, Group1]

Result:  [2, 3, 5, 7,    1, 4, 6, 8]

答案 1 :(得分:2)

  

为什么我们两次回来?

这与闭包或嵌套函数无关。

def helper(x):
    if  x  in  group:
        return  (0, x)
    return  (1, x)

可以写成

def helper(x):
    if  x   in  group:
        return  (0, x)
    else:        
        return  (1, x)

无论哪种方式,返回值都取决于if语句的计算结果。 如果是True,则会返回(0, x)。如果是False,则会返回(1, x)

答案 2 :(得分:1)

请注意,第一个return语句位于if块中。在python中,只要函数遇到return语句,执行就会返回给调用者 在您的示例中,两个返回只是避免if语句的快捷方式。当特定值在组中时,将返回(0,x),如果不满足if条件,则返回(1,x)

答案 3 :(得分:1)

在没有嵌套函数的情况下编写代码时,它更容易理解:

def helper(x):
    global group
    if x in group:
        return 0, x
    return 1, x


def sort_priority(values):
    values.sort(key=helper)


numbers = [8, 3, 1, 2, 5, 4, 7, 6]
group = {2, 3, 5, 7}
sort_priority(numbers)
print(numbers)

现在很容易看到sort_priority()只是通过调用helper函数来对值进行排序,该函数通过为每个x分配值来创建订单。

当使用helper中的值调用group函数时,它会降低&#34;降低&#34;优先级(零),如果该值不在group中,则优先级更高(一)。

仔细观察helper确实显示:

def helper(x):
    global group
    if x in group:
        return 0, x  # <-- we're in the `if` so `x` gets zero 
    return 1, x      # <-- if we got here it means we didn't get into the `if` so `x` gets one

因此,在排序中使用helper作为key函数,我们将获取并排序列表,这些列表首先放置group中的项目,然后才不在group中的项目:

[2, 3, 5, 7, 1, 4, 6, 8]
             ^
            The first item that is not in group