逗号在这个任务中做了什么?

j.d*_*doe 3 python try-catch variable-assignment python-2.7 iterable-unpacking

我对Python语法不太熟悉,并且想知道是否有人可以向我解释变量match是如何for对此函数中的表达式中找到的字符串进行的:

def find_project(project_name):    
    projects = get_projects()    
    try:
        match, = (proj for proj in projects if proj["name"].strip() == project_name)
        return match
    except ValueError:
        return None
Run Code Online (Sandbox Code Playgroud)

Zer*_*eus 6

Python允许您一次分配多个变量,如下所示:

a, b = 1, 2
Run Code Online (Sandbox Code Playgroud)

这种方法的工作方式是将赋值的左侧a, b视为元组,并将1, 2右侧元组中的每个元素赋值给它.

由于元组只能有一个元素,因此以下也可以:

a, = 1,
Run Code Online (Sandbox Code Playgroud)

多重赋值的右侧不一定是元组.任何迭代都可以,只要每边的元素数量相同:

a, b, c = "three little pigs".split()
Run Code Online (Sandbox Code Playgroud)

如果元素数量不匹配:

a, b, c = "oh", "no"
Run Code Online (Sandbox Code Playgroud)

你得到一个ValueError:

ValueError: not enough values to unpack (expected 3, got 2)
Run Code Online (Sandbox Code Playgroud)

将以上所有内容放在一起,然后,您的功能:

def find_project(project_name):    
    projects = get_projects()    
    try:
        match, = (proj for proj in projects if proj["name"].strip() == project_name)
        return match
    except ValueError:
        return None
Run Code Online (Sandbox Code Playgroud)

...迭代生成器表达式

(proj for proj in projects if proj["name"].strip() == project_name)
Run Code Online (Sandbox Code Playgroud)

...如果结果有一个元素,则将该元素分配给match.如果没有,ValueError则引发(并被except子句捕获),不会发生任何赋值,并None返回.

有两点需要注意:

  1. ,阅读代码时很容易错过逗号.另一种方法是在左侧使用列表语法:

    [match] = (proj for proj in projects if proj["name"].strip() == project_name)
    
    Run Code Online (Sandbox Code Playgroud)

    ...具有相同的效果.

  2. 当右侧是生成器表达式(或其他类型的迭代器)时,您可以使用next()默认值:

    def find_project(project_name):    
        projects = get_projects()    
        it = (proj for proj in projects if proj["name"].strip() == project_name)
        return next(it, None)
    
    Run Code Online (Sandbox Code Playgroud)

    ......更短,更易读.