【问题标题】:Find the index of a partial dictionary element in a list在列表中查找部分字典元素的索引
【发布时间】:2010-11-11 17:37:03
【问题描述】:

我有一个字典列表如下:

myList=[{'id':1,'key1':'a','key2':'b'},{'id':8,'key1':'c','key2':'d'}, 
        {'id':6,'key1':'a','key2':'p'}]

要查找元素的索引,我目前正在执行以下语句:

print myList.index({'id':8,'key1':'c','key2':'d'})

返回 1

但是,我想做这样的事情:

print myList.index({'id':8})

应该返回 1

【问题讨论】:

  • 出于好奇,你为什么需要这个?它看起来像是值得重新考虑数据结构的事情,尽管不一定如此。
  • @katrielalex:我正在构建的数据结构是另一个需要数据符合特定标准的过程的要求。

标签: python dictionary indexing


【解决方案1】:

如果您正在寻找单行代码(而不是可重用代码),并且您的数据量很小,您可以执行以下操作:

[elem["id"] for elem in myList].index(8)

从每个dict中提取id,然后找到提供的id的索引。根据您的总体目标和数据集的样子,这可能是也可能不是您想要的......

【讨论】:

  • 嗯,这很快,可以解决我在这个特定解决方案中的问题。非常感谢这个。但是,@martineau 的回答更通用、更有用。
【解决方案2】:

应该比较容易实现。为 Python 3 编写,在 Python 2 中您应该使用 .iteritems()(不会创建临时列表)。

def partial_dict_index(dicts, dict_part):
    for i, current_dict in enumerate(dicts):
        # if this dict has all keys required and the values match
        if all(key in current_dict and current_dict[key] == val 
                for key, val in dict_part.items()):
            return i
    raise ValueError("...")

虽然可以使用更好的名称...

【讨论】:

  • -1 因为for i, current_dict in dicts: 行导致ValueError: too many values to unpack 与Python 3 vs Python 2 和iteritems() 的使用无关(因为dictslist ,而不是字典)。
  • @martineau:我只是忘记了枚举调用。修好了。
  • 好吧,这样更好,我将删除我的反对票——您真的应该在将代码发布到此处之前对其进行测试。然而,我不会投票赞成它,因为尽管它现在可以运行、工作并且很短,但它仍然具有潜在的二级或二次计算时间复杂度 O(n1xn2),这可以大大改进。
  • @martineau:再来一次?我看不出all(key in nth_dict for key, _ in dict.items()) 的复杂性如何比len(filter(nth_dict.has_key, dict.keys())) == key_count 更差。事实上,只要有一个不在partial 中的键,“mine”就会停止搜索nth_dict,而“yours”总是检查所有键!另外,我认为最坏的情况大 O 无论如何都会是 (n1 * n2),因为为了 raise,我们需要看到没有一个字典等于所有 partial(这也是你的代码所做的) ...还是我弄错了?
  • 不,你没有弄错表现,我是并且道歉。也就是说,我现在觉得你的正确答案是两者中更快的一个。
【解决方案3】:

编辑:请将您接受的答案更改为@delnan 的更正答案,该答案非常相似并且可能表现更好。

【讨论】:

  • 非常感谢您提供这个通用解决方案。很有帮助。
【解决方案4】:

您可以实现自己的列表。这是一个打印第一个找到的结果的示例。我添加了 ValueError 以复制 .index() 的现有行为。

class DictList(list):

    def index(self, obj):
        for i, o in enumerate(self):
            if o['id'] == obj['id']:
                return i
        else:
            raise ValueError('x not in list')


myList = DictList(({'id':1,'key1':'a','key2':'b'},{'id':8,'key1':'c','key2':'d'}, 
                   {'id':6,'key1':'a','key2':'p'}))

>>> print myList.index({'id': 8})
1

>>> print myList.index({'id': 10})
ValueError: x not in list

【讨论】:

  • -1 因为index() 方法搜索的键是硬编码的(到'id'),而且它假设这是obj 中唯一需要匹配的(key.value)对。恕我直言,抽象的“DictList”类需要有一个更通用和通用的方法。
  • 没有什么抽象的。这是一个列表的实现,旨在以最接近于他期望结果的方式解决发布者的问题,而不是实现理论字典列表的所有可能用途。
  • 也许你应该把它称为比DictList 更不通用的东西。我相信将值硬编码到代码中是一种极差的做法,因此至少即使在非通用例程中,键值也应该作为类属性或作为具有默认值的关键字参数传递给 index() 方法。这样做将允许在单个位置更改其值,而不是在现有代码中的每次出现时更改。
猜你喜欢
  • 2014-09-17
  • 2021-02-27
  • 1970-01-01
  • 2013-07-26
  • 2021-06-25
  • 1970-01-01
  • 2010-12-02
  • 1970-01-01
  • 2014-09-03
相关资源
最近更新 更多