在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.find
和str.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中按属性获取对象列表中的索引的主要内容,如果未能解决你的问题,请参考以下文章