【问题标题】:Python Iterate over NoneTypePython 遍历 NoneType
【发布时间】:2016-12-20 22:09:55
【问题描述】:

我有以下代码,并试图迭代每一行的结果并检查“未训练”字典中的计算值是否大于 50%。但是,有些行是 NoneType 并且我收到错误:TypeError: 'NoneType' oject is not subscriptable。有没有办法我可以避免这种情况并仍然迭代以获得我想要的输出?

from collections import namedtuple
from itertools import zip_longest

trained = {'Dog': 4, 'Cat': 3, 'Bird': 1, 'Fish': 12, 'Mouse': 19, 'Frog': 6}
untrained = {'Cat': 6, 'Mouse': 7, 'Dog': 3, 'Wolf': 9}

Score = namedtuple('Score', ('total', 'percent', 'name'))

trained_scores = []
for t in trained:
    trained_scores.append(
        Score(total=trained[t],
              percent=(trained[t]/(trained[t]+untrained.get(t, 0)))*100,
              name=t)
    )

untrained_scores = []
for t in untrained:
    untrained_scores.append(
        Score(total=untrained[t],
              percent=(untrained[t]/(untrained[t]+trained.get(t, 0)))*100,
              name=t)
    )

# trained_scores.sort(reverse=True)
# untrained_scores.sort(reverse=True)

row_template = '{:<30} {:<30}'
item_template = '{0.name:<10} {0.total:>3} ({0.percent:>6.2f}%)'
print('='*85)
print(row_template.format('Trained', 'Untrained'))
print('='*85)

for trained, untrained in zip_longest(trained_scores, untrained_scores):
    x = row_template.format(
        '' if trained is None else item_template.format(trained),
        '' if untrained is None else item_template.format(untrained)
    )
    print(x)

电流输出:

=====================================================================================
Trained                        Untrained                     
=====================================================================================
Mouse       19 ( 73.08%)       Mouse        7 ( 26.92%)      
Cat          3 ( 33.33%)       Cat          6 ( 66.67%)      
Frog         6 (100.00%)       Wolf         9 (100.00%)      
Dog          4 ( 57.14%)       Dog          3 ( 42.86%)      
Bird         1 (100.00%)                                     
Fish        12 (100.00%) 

期望的输出:

=====================================================================================
Trained                        Untrained                     
=====================================================================================
Mouse       19 ( 73.08%)       Mouse        7 ( 26.92%)       
Cat          3 ( 33.33%)       Cat          6 ( 66.67%)  <-- Above 50%    
Frog         6 (100.00%)       Wolf         9 (100.00%)  <-- Above 50%      
Dog          4 ( 57.14%)       Dog          3 ( 42.86%)      
Bird         1 (100.00%)                                     
Fish        12 (100.00%)                                     

更新!

使用有效的建议代码进行了更新。感谢大家的帮助!

if untrained is not None and untrained[1] > 50:
    print(x + '<-- Above 50%')
else:
    print(x)

结果:

=====================================================================================
Trained                        Untrained                     
=====================================================================================
Mouse       19 ( 73.08%)       Wolf         9 (100.00%)       <-- Above 50%
Fish        12 (100.00%)       Mouse        7 ( 26.92%)      
Frog         6 (100.00%)       Cat          6 ( 66.67%)       <-- Above 50%
Dog          4 ( 57.14%)       Dog          3 ( 42.86%)      
Cat          3 ( 33.33%)                                     
Bird         1 (100.00%)        

【问题讨论】:

  • total=trained[t] 是什么意思?当你循环for t in trained:时,t已经包含了你需要的元素,而不是元素的索引。
  • @IgorPomaranskiy 在dict 上迭代会返回它的键...所以trained[t] 将访问它的值...
  • @JonClements 对不起,你是对的,我的错!

标签: python dictionary nonetype


【解决方案1】:

您不能只跳过untrainedNone 的行,否则您也将跳过trained 值。相反,您应该直接向if 条件添加额外的保护,检查百分比是否 > 50:

if untrained is not None and untrained[1] > 50:
    print(x + '<-- Above 50%')
else:
    print(x)

【讨论】:

  • 就是这样!没想到要添加额外的'and'语句。我希望宇宙奖励你和今天帮助我的一切。非常感谢!
  • 有什么技巧可以把它折叠成一条短线吗?我有一个分层树,我编写了自定义迭代器来跳过流指针下游的空值,但我仍然必须明确检查当前元素是否不为空,并且每次执行时都要使用一个 if 语句和一个缩进。
【解决方案2】:

跳过无值

if untrained is None:
    continue

【讨论】:

  • 或者在更 Pythonic 的版本中,if not untrained:
  • @DeepSpace 我不建议使用这种方法。有时它是可靠的,但有时不是。 if not untrained 不仅会跳过Nones,还会跳过0s 和空数据结构(列表、元组、集合等),这可能是不希望的,有时很难找出结果不正确的原因.所以最好做显式比较:if untrained is not None:.
  • @Akilesh 我添加了建议的代码,但现在我缺少第一列中的一些值(经过培训)。我粘贴了上面修改过的代码及其结果。你能检查一下我做错了什么吗?
猜你喜欢
  • 1970-01-01
  • 2021-04-25
  • 2019-08-04
  • 1970-01-01
  • 1970-01-01
  • 2012-05-05
  • 2013-02-18
  • 2012-07-12
  • 2013-03-02
相关资源
最近更新 更多