2010-11-11 72 views
3

我有字典的名单如下:查找部分字典元素的索引列表中的

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

+1

出于好奇,你为什么需要这个?它看起来像是可能需要重新考虑数据结构的那种事情,尽管并非如此。 – katrielalex 2010-11-11 17:43:31

+0

@katrielalex:我正在构建的数据结构是另一个需要数据符合特定标准的过程的要求。 – jitendra 2010-11-12 09:34:47

回答

1

应该比较容易实现。为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("...") 

能更好的名字,但...

+0

-1,因为''for i,current_dict in dicts:'结果为一个'ValueError:太多的unpack值',这与Python 3与Python 2无关并且使用'iteritems()'(因为' dicts'是一个'list',而不是字典)。 – martineau 2010-11-11 18:44:01

+0

@martineau:我只是忘记了枚举调用。修复。 – delnan 2010-11-12 15:44:36

+0

好吧,这会更好,我会删除我的投票 - 你真的应该在发布之前测试代码。但是我不会对它投票,因为尽管它现在运行,工作,并且很短,但它仍然具有潜在的第二度或二次计算时间复杂度O(n1xn2),这可能会大大改善。 – martineau 2010-11-12 21:40:05

-1

您可以实现自己的列表。这是一个打印第一个找到的结果的例子。我添加了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 
+0

-1因为'index()'方法搜索的关键字是硬编码的(对'id''),并且它假定'obj'中唯一的(key.value)对需要匹配。恕我直言,一个抽象的“DictList”类将需要有一个更通用和一般的方法。 – martineau 2010-11-11 19:09:29

+0

没有什么关于它的抽象。这是一个列表的实现,旨在以最接近模仿他所期望的结果的方式解决海报的问题,而不是实现理论字典列表的所有可能用途。 – 2010-11-11 19:47:55

+0

也许你应该把它称为不像DictList的泛型。我相信将代码硬编码到代码中是一种极其糟糕的做法,因此至少即使在非常规例程中,键值也应该作为类属性或作为关键字参数传递给'index()'方法,其默认值。这样做可以使其值在一个地方而不是在现有代码中的每一处出现。 – martineau 2010-11-11 21:40:24

1

如果你正在寻找一个班轮(而不是可重用的代码),以及您的数据量很小,你可以这样做:

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

从提取ID每个字典,然后找到提供的ID的索引。根据您的总体目标和数据集的样子,这可能会或可能不会是你想要的...

+0

好吧,那很快就能解决我对这个特定解决方案的问题。感谢这一个很多。但是,@ martineau的答案更通用,更实用。 – jitendra 2010-11-12 09:24:50

1

编辑:请更改您接受的答案@ delnan的更正答案,这是非常相似,可能会表现更好。

+0

非常感谢您提供这种通用解决方案。非常有帮助。 – jitendra 2010-11-12 09:19:42