找到每个字典,每个字典都有不确定数量的已定义键

时间:2012-02-20 23:20:16

标签: python

我有关于一堆不同物品的信息。每个项目都有自己的字典,其中包含有关该项目的信息,我有一个更大的字典,其中存储了每个项目。但是,我没有为每个项目提供所有相同的信息。例如,假设我的物品是水果。然后结构看起来像:

fruit = {}
fruit['apple'] = {'color': 'red', 'origin': 'Washington'}
fruit['banana'] = {'color': 'yellow'}
fruit['orange'] = {'color': 'orange', 'origin': 'Florida'}

如果我想找到已经定义的每种水果的来源,我正在做以下事情:

fruits, origins = zip(* [(f, fruit[f]['origin']) for f in fruit.keys() if 'origin' in fruit[f]])

工作正常。一旦我想找到同时定义了颜色和原点的每种水果,它就开始变得难看。

fruits, origins, colors = zip(* [(f, fruit[f]['origin'], fruit[f]['color']) for f in fruit.keys() if 'origin' in fruit[f] and 'color' in fruit[f]])

我想要做的是能够编写一个通用函数,为任意数量的指定键执行此操作。也就是说,我可以调用一些名为“defined”的函数来获取字典字典,以及子字典中的键或键列表,并返回所有具有每个键定义的子字典,以及每个键的值。

fruits, origins = defined(fruit, ['origin'])
fruits, origins, colors = defined(fruit, ['origin', 'color'])

我已经查看了各种现有线程,其中包含有关从字典中获取键/值对的问题,但我没有找到任何看起来正确的内容。是否有一种相当直接的方式来概括这一点?

或者,如果人们还想告诉我我应该以完全不同的方式组织我的数据,我也欢迎这样做。我最初选择了字典词典,因为每个项目都有广泛的信息。例如,一些子词典有数十个带有信息的条目,有些项只有几个条目(也就是说,'apple'词典有很多信息,但我没有太多的存储在'金橘'中)。

2 个答案:

答案 0 :(得分:4)

您可以按列表推导来概括值提取,and序列按all推广:

def defined(dct, keys):
    return zip(*[([k] + [v[m] for m in keys])
                 for k, v in dct.iteritems()
                 if all(m in v for m in keys)])

答案 1 :(得分:2)

这是一个以与示例调用建议的方式略有不同的方式返回数据的函数:它将返回一个迭代器,它迭代所有必需字段的所有字典条目。

def defined(fruits, attr_names):
    getter = operator.itemgetter(*attr_names)
    for f, d in fruit.iteritems():
        try:
            attrs = getter(d)
        except KeyError:
            continue
        else:
            yield (f,) + attrs

实施中唯一可能值得一提的是operator.itemgetter()。像

这样的电话
operator.itemgetter(['origin', 'color'])

返回一个函数,该函数应用于字典,将返回键'origin''color'的值作为元组。如果其中一个键无法启动,则字典将像往常一样抛出KeyError

您可以在返回的迭代器上使用zip()以您建议的方式使用此函数:

fruits, origins, colors = zip(*defined(fruit, ['origin', 'color']))