【问题标题】:Can't index a dict in a list comprehension无法在列表理解中索引 dict
【发布时间】:2016-07-20 17:24:35
【问题描述】:

我正在尝试从dicts 的list 中提取list。 列表中的每个dict 都有一个键值映射。我想为 list 包含的每个 dict 中映射的单个值创建一个 list

查看下面的代码和输出,以交互形式编写。

>>> print(str(param_to_outputs_dict_dict))
{('max_features', 1558): {'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=1558, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}, 
('max_features', 7713): {'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=7713, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
>>> print()

在上面我们看到param_to_outputs_dict_dict 是两个条目的dict。每个条目的键是tuple,值是dict

接下来,我使用列表解析来提取值的listdict 类型)

>>> map_list = [output_dict for output_dict in list(param_to_outputs_dict_dict.values())]
>>> print(str(map_list))
[{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=1558, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}, 
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=7713, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}]
>>> print()

我们看到这也有效。我们有一个 list 包含两个 dicts,它们是 param_to_outputs_dict_dict 中包含的值。

现在,我不提取字典,而是尝试提取每个字典中由值 'classifier' 映射的值。

>>> classifier_list = [output_dict['classifier'] for output_dict in list(param_to_outputs_dict_dict.values())]
>>> print(str(classifier_list))


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-176-b6f236339c69> in <module>()
      8 print(str(map_list))
      9 print()
---> 10 classifier_list = [output_dict['classifier'] for output_dict in list(param_to_outputs_dict_dict.values())]
     11 print(str(classifier_list))
     12 print()

<ipython-input-176-b6f236339c69> in <listcomp>(.0)
      8 print(str(map_list))
      9 print()
---> 10 classifier_list = [output_dict['classifier'] for output_dict in list(param_to_outputs_dict_dict.values())]
     11 print(str(classifier_list))
     12 print()
TypeError: 'DecisionTreeClassifier' object is not subscriptable

但是,这不起作用。错误消息让我认为 Python 将 output_dict 解释为 DecisionTreeClassifier 类型,但我不知道为什么。我已经玩了几个小时这个问题,但完全被难住了。

我怀疑解决方案对其他人来说可能非常明显!提前致谢!

编辑:原始帖子中缺少关键信息

为了使问题更简短、更清晰,我将打印结果截断为仅包含任何集合的前两个元素。然而,在意识到问题之后(见下面我的回答),当给出完整列表时,问题的原因就非常明显了。见下文,特别是列表的最后一个元素。

>>> for value in list(param_to_outputs_dict_dict.values()):
>>>     print(str(value))
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=10,
        max_features=None, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=100,
        max_features=None, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=-100, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=3, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=-10000, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=7791, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=77, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=100000,
        max_features=None, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=1558, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=1,
        max_features=None, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=3895, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=7713, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=7011, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight='balanced', criterion='gini',
        max_depth=None, max_features=None, max_leaf_nodes=None,
        min_samples_leaf=1, min_samples_split=2,
        min_weight_fraction_leaf=0.0, presort=False, random_state=None,
        splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='random')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=-1000, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=779, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=10000,
        max_features=None, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=-1, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=1000, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=10, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=1000,
        max_features=None, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=10000, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=6232, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=100, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='entropy', max_depth=None,
        max_features=None, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=88, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=-10, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=100000, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
{'classifier': DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=-100000, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')}
DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
        max_features=None, max_leaf_nodes=None, min_samples_leaf=1,
        min_samples_split=2, min_weight_fraction_leaf=0.0,
        presort=False, random_state=None, splitter='best')

【问题讨论】:

  • 我个人看不出有什么问题。我不知道你的 DecisionTreeClassifier 类是什么样的,但是用我编的这个假的,它似乎运行良好:ideone.com/uzNw17
  • @DavidWhite 感谢您为我运行它。嗯,这很令人困惑!仅供参考,我在我的代码中使用来自 scikit-learn 的 sklearn.tree.DecisionTreeClassifier。

标签: dictionary scikit-learn list-comprehension python-3.5


【解决方案1】:

查看问题中打印的完整列表,我们可以看到最后一个元素不是包含单个 strDecisionTreeClassifier 映射的 dict 类型,而是简单的 DecisionTreeClassifier 类型。

因此,以下代码:

[output_dict['classifier'] for output_dict in list(param_to_outputs_dict_dict.values())]

list(param_to_outputs_dict_dict.values()) 的每个元素分配给output_dict 在最后一个元素处分配DecisionTreeClassifier

因此,在该迭代中,语句 output_dict['classifier'] 尝试下标 DecisionTreeClassifier 对象,不是 dict。这会产生问题中给出的TypeError

【讨论】:

    【解决方案2】:

    您正在做一些多余的事情。以下是实现的方法。

    [v["classifier"] for v in param_to_outputs_dict_dict.values()]
    

    list(dict.values())[v for v in dict.values()] 是同一个东西,那么[v for v in list(dict.values())] 的语义是什么。在同一行中,print(str(x)) 到底是什么? print(x) 输出 x.__str__()。当我说冗余时,这就是我的意思。

    【讨论】:

    • 在 Python 3 中,dict.values() 返回一个视图,而不是一个列表。该视图不可索引,并且如果基础 dict 更改,则会更改。因此,您的实现不太线程安全。
    • 另外,我更喜欢显式转换数据;说str(x)x 的字符串表示形式)对我来说看起来更清楚,而不是将非字符串类型传递给print 并依靠它来读懂我的想法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-15
    • 2013-12-23
    • 1970-01-01
    • 2021-11-20
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多