在Python中按属性获取对象列表中的索引

Posted

技术标签:

【中文标题】在Python中按属性获取对象列表中的索引【英文标题】:Get index in the list of objects by attribute in Python 【发布时间】:2013-10-10 08:01:01 【问题描述】:

我有具有属性 id 的对象列表,我想查找具有特定 id 的对象的索引。我写了这样的东西:

index = -1
for i in range(len(my_list)):
    if my_list[i].id == 'specific_id'
        index = i
        break

但它看起来不太好。有没有更好的选择?

【问题讨论】:

按索引循环是 Python 中一个非常大的反模式 - 直接在列表上循环。 【参考方案1】:

当您需要 for 循环中的值和索引时,请使用 enumerate

for index, item in enumerate(my_list):
    if item.id == 'specific_id':
        break
else:
    index = -1

或者,作为生成器表达式:

index = next((i for i, item in enumerate(my_list) if item.id == 'specific_id'), -1)

【讨论】:

但是“-1”是一个有效的索引值。如果您的代码没有找到匹配项,它将返回 -1 的索引,并引导某人将列表的最后一个元素视为匹配。 @CPBL 是的。在 else 子句中提出 ValueError 肯定会更加 Pythonic(以反映 list.index 的行为)。【参考方案2】:

这是一种不使用(显式)循环的替代方法,它使用两种不同的方法从原始列表生成“id”值列表。

try:
    # index = map(operator.attrgetter('id'), my_list).index('specific_id')
    index = [ x.id for x in my_list ].index('specific_id')
except ValueError:
    index = -1

【讨论】:

这仅在 python 3 中吗?使用 python 2.7.4 'find' 不存在 - 在列表中查找元素索引的方法称为 'index'。 不,这似乎是一个灾难的答案。我不仅似乎假设有一个list.find 类似于str.findstr.index 方法对,而且还混淆了哪个引发ValueError(它是str.index,而不是str.find)并返回-1。现在更正为list.index【参考方案3】:

你可以使用enumerate:

for index, item in enumerate(my_list):
    if item.id == 'specific_id':
        break

【讨论】:

【参考方案4】:

为您的类实现__eq__ 方法

class MyCls:
   def __init__(self, id):
       self.id = id

   def __eq__(self, other):
       # comparing with str since you want to compare
       # your object with str

       if not isinstance(other, str):
           raise TypeError("MyCls can be compared only with str")
       if other == self.id:
           return True
       return False

现在你可以做类似的事情

my_list = [MyCls(i) for i in 'abcdef']
print(my_list.index('c'))

这将返回索引 2。它的行为类似于普通的 list.index 方法的行为。即如果它没有找到索引,它将引发 ValueError

【讨论】:

【参考方案5】:

假设

a = [1,2,3,4]
val = 3

a.index(val) if val in a else -1

对于多次出现,根据以下 Azam 的评论:

[i if val == x else -1 for i,x in enumerate(a)] 

编辑1: 对于所有评论其对象列表的人,您只需访问id

[i if val == x.id else -1 for i,x in enumerate(a)] 

【讨论】:

如果我们正在搜索的 val 数字是重复的,例如 a=[1,2,3,4,3,7,9]???? a = [1,2,3,4] 是一个对象列表吗?请在回答前阅读操作员的问题 这不是对象列表

以上是关于在Python中按属性获取对象列表中的索引的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中按列表中的项目分组

如何使用 Python 获取列表列表中最大列表的索引?

如何在javascript中按属性查找数组中的对象?

如何在javascript中按属性查找数组中的对象?

在javascript数组中按值获取索引

从具有对象属性之一的对象列表中获取索引