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

时间:2017-03-10 19:12:48

标签: python python-2.7 try-catch variable-assignment 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

1 个答案:

答案 0 :(得分:6)

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

a, b = 1, 2

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

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

a, = 1,

多项任务的右侧并不一定是元组。任何迭代都可以,只要每边的元素数量相同:

a, b, c = "three little pigs".split()

如果元素的数量不匹配:

a, b, c = "oh", "no"

...你得到ValueError

ValueError: not enough values to unpack (expected 3, got 2)

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

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

...遍历generator expression

(proj for proj in projects if proj["name"].strip() == project_name)

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

有两点需要注意:

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

    [match] = (proj for proj in projects if proj["name"].strip() == project_name)
    

    ......具有相同的效果。

  2. 如果右侧是生成器表达式(或其他类型的iterator),则可以使用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)
    

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