【问题标题】:Why a "'NoneType' is not iterable" error when I am not iterating?为什么在我不迭代时出现“'NoneType' 不可迭代”错误?
【发布时间】:2014-03-04 16:55:29
【问题描述】:

运行以下脚本时

dictlist = [
    {'a': 'hello world', 'b': 'my name is Bond'},
    {'a': 'bonjour monde'}
]

for d in dictlist:
    if 'Bond' not in d.get('b'):
        print d

我希望输出为空(第一个 dict 不匹配,第二个缺少密钥 'b')但我收到错误:

Traceback (most recent call last):
  File "C:/dev/mytest.py", line 7, in <module>
    if 'Bond' not in d.get('b'):
TypeError: argument of type 'NoneType' is not iterable

我很困惑:为什么在我不迭代时会出现argument of type 'NoneType' is not iterable 错误(至少在那一行)?

我确信这是一个明显的错误,但我查看代码的次数越多,我看到它的机会就越少:)

【问题讨论】:

    标签: python iterable


    【解决方案1】:

    您确实在迭代,因为这就是操作员in 的工作方式。当你这样做时:if 'Bond' not in d.get('b'): Python 将在左操作数 (d.get('b')) 中查找 'Bond'd.get('b') == None 在第二个条目中因此异常。

    您可以将第二个参数传递给get,这将被解释为默认值,以防找不到缓解此if 子句的元素:

    if 'Bond' not in d.get('b',[]):
    

    【讨论】:

      【解决方案2】:

      在第二次迭代中,d 将是 {'a': 'bonjour monde'},它没有密钥 b。 如果未找到密钥,d.get('b') 将返回 None,因为 dict.get 将返回 Nonein 运算符将 RHS 视为可迭代的。这就是您收到此错误的原因。

      你可以像这样简单地避免这种情况

      for d in dictlist:
          if 'b' in d and 'Bond' not in d['b']:
      

      【讨论】:

      • 谢谢。所有响应都很棒——感谢额外的位(默认值不会有帮助,因为它会匹配if
      • @WoJ 不,仅默认值将不匹配。如果您有不同的理解,请告诉我。
      • 如果我使用if 'Bond' not in d.get('b',"") 那么当'b' 不存在时,将返回一个空字符串,它将与if 'Bond' not in 匹配——这不是我想要的('b' 是根本不存在,所以测试(从逻辑角度)是无效的)。 您的代码正常:i) 'b' 必须存在,以便 ii) 检查 'Bond'
      • @WoJ 哦,如果那是您的用例,那么您是完全正确的先生.. :) 但这对于这种特殊情况也同样适用,if 'Bond' not in d.get('b',[]): 因为它返回一个空列表并且Bond 不会出现在空列表中,因此条件将失败。 :)
      • 是的,当然,代码是可以的,默认的空字符串条件会失败。我的意思是,从设计/逻辑的角度来看,我不希望它在没有要检查的密钥时失败——而您的代码示例正是这样做的(仅在有密钥时才检查。
      【解决方案3】:

      使用d.get('b', '') 而不是d.get('b')

      默认情况下,dict.get 如果您提供的键不存在,则返回 None,这不是可迭代的或有任何方法可调用。所以只需将一个额外的参数传递给get 以避免默认返回值None。请参阅文档字符串:

      D.get(k[,d]) -> D[k] 如果 k 在 D 中,否则 d。 d 默认为无。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-13
        • 2016-09-11
        • 2020-03-18
        • 2014-10-09
        • 2019-01-10
        • 2019-10-23
        • 1970-01-01
        • 2013-12-01
        相关资源
        最近更新 更多