【问题标题】:What is the comma doing in this assignment? [duplicate]这个作业中的逗号是做什么的? [复制]
【发布时间】:2017-08-01 06:01:18
【问题描述】:

我对 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

【问题讨论】:

    标签: python python-2.7 try-catch variable-assignment iterable-unpacking


    【解决方案1】:

    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)
      

      ...更短更易读。

    【讨论】:

      猜你喜欢
      • 2019-10-20
      • 2018-10-24
      • 2012-05-22
      • 2016-03-28
      • 1970-01-01
      • 1970-01-01
      • 2012-02-16
      • 2016-04-06
      • 1970-01-01
      相关资源
      最近更新 更多