【问题标题】:Error handling for list comprehension in PythonPython中列表理解的错误处理
【发布时间】:2018-03-11 19:48:12
【问题描述】:

有没有办法处理 python 列表理解中的错误。我最好有这样的东西,其中最后两个值由None 表示:

values = [try i ["row"] except KeyError None for i in [{"row" : 1}, {"Row" : 0}, {}]]

这会引发语法错误,我能做到的唯一方法是:

values = []
for i in [{"row" : 1}, {"Row" : 0}, {}]:
    try: values.append (i ["row"])
    except KeyError: values.append (None)

我希望有一种更“简洁”的方式来执行此操作,因为当前的解决方案并不可取,因为当列表理解以如此好的方式执行此操作时必须附加到空白列表!

【问题讨论】:

  • 代码中的任何地方都没有生成器。你的意思是列表理解
  • 1) 我改变了我的问题,因为我的意思是列表理解 2) 我不介意列表中是否有 None,因为我正在检查返回的值

标签: python python-3.x generator


【解决方案1】:

您无法从列表理解中捕获异常 (How can I handle exceptions in a list comprehension in Python?)。但考虑到你想做的事情,你可以使用get:

values = [i.get("row") for i in [{"row" : 1}, {"Row" : 0}, {}]]

如果在字典get 中找不到键,则返回None,这正是您要查找的内容(它可以返回您想要的任何内容,只需将默认值作为第二个参数传递,请参阅Why dict.get(key) instead of dict[key]? )

【讨论】:

    【解决方案2】:

    您还可以在列表理解中检查键是否为dictionary,如果不存在则返回None

    key = 'row'
    values = [i[key] if key in i else None for i in [{"row" : 1}, {"Row" : 0}, {}]]
    

    【讨论】:

      【解决方案3】:

      您不能在列表推导中直接处理异常,因为try 是一个语句,而不是一个表达式。

      但是,您可以将try 抽象为一个单独的函数:

      def tryirow(i):
          try: return i["row"]
          except KeyError: return None
      
      values = [tryirow(i) for i in [{"row" : 1}, {"Row" : 0}, {}]]
      

      当然,在这种情况下,正如Jean-François Fabre's answer 所暗示的那样,您刚刚重新实现了内置的dict.get 方法:

      values = [i.get("row") for i in [{"row" : 1}, {"Row" : 0}, {}]]
      

      但这显示了您如何更普遍地解决类似问题:如果有一个函数可以满足您的需求,请调用它;如果没有,就写吧。


      当然有时,“写出for 声明”实际上是正确答案。不是所有的东西都应该写成列表理解,即使是很多东西可以。我认为这与此处无关,但值得牢记。


      实际上有人提议添加一个try 表达式,就像您要编写的表达式PEP 463 一样。为什么被拒绝了?因为几乎所有用例都是“get-with-default-fallback”案例,其中您想要的功能已经存在(如dict.get)或应该存在。没有人能想出一个用单独的函数或扩展的for 语句编写的通用用例。

      在一种全新的语言中,我认为使用 try 表达式而不使用 dict.get 之类的方法会更有意义,但使用在有人建议之前已经使用 dict.get 十多年的语言try 表达(比任何人提出具体建议早了近 20 年),这将是一个糟糕的改变。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-28
        • 2023-04-05
        • 1970-01-01
        • 2018-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多