无法在列表理解中索引字典

Can't index a dict in a list comprehension

我正在尝试从 dictlist 中提取 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.

接下来,我使用列表理解来提取 list 个值(dict 类型)

>>> 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()

我们看到这也奏效了。我们有一个包含两个 dictlist,它们是 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 类型,但我不知道为什么。我已经解决这个问题好几个小时了,但完全被难住了。

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

编辑:原始 post

中缺少关键信息

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

>>> 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')

查看问题中打印的完整列表,我们可以看到最后一个元素不是包含单个 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

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

[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__()。这就是我说冗余时的意思。