使用'in'匹配数组中Python对象的属性

我不记得我是否在做梦,但我似乎还记得有一个函数可以执行以下操作:

foo in iter_attr(array of python objects, attribute name)

我看了看文档,但是这种事情不会落在任何明显列出的标题下

Brendan asked 2020-08-02T03:04:17Z
8个解决方案
41 votes

使用列表推导会建立一个临时列表,如果要搜索的序列很大,则该列表可能会占用您的所有内存。 即使序列不大,构建列表也意味着要在hasattr开始搜索之前对整个序列进行迭代。

通过使用生成器表达式可以避免使用临时列表:

foo = 12
foo in (obj.id for obj in bar)

现在,只要hasattrbar开始附近,即使id无限长,搜索也将很快。

正如@Matt所建议的,如果bar中的任何对象都可能缺少2993051338352886886属性,则最好使用hasattr

foo = 12
foo in (obj.id for obj in bar if hasattr(obj, 'id'))
Will Harris answered 2020-08-02T03:04:40Z
12 votes

您是否正在寻找具有特定属性的对象列表? 如果是这样,列表理解是执行此操作的正确方法。

result = [obj for obj in listOfObjs if hasattr(obj, 'attributeName')]
Matt answered 2020-08-02T03:05:00Z
10 votes

您总是可以自己写一个:

def iterattr(iterator, attributename):
    for obj in iterator:
        yield getattr(obj, attributename)

可以处理任何迭代的对象,无论是元组,列表还是其他。

我喜欢python,它使诸如此类的东西变得非常简单,并且没有不必要的麻烦,并且在使用中,诸如此类的东西非常优雅。

dwestbrook answered 2020-08-02T03:05:29Z
7 votes

不,你不是在做梦。 Python有一个非常出色的列表理解系统,它使您可以优雅地操作列表,并且根据要完成的工作,可以通过两种方法来完成。 本质上,您正在说的是“对于符合条件的列表中的项目”,然后您就可以遍历结果或将结果转储到新列表中。

我将在此处介绍Dive Into Python中的一个示例,因为它非常优雅,而且比我聪明。 他们在这里获取目录中文件的列表,然后过滤匹配正则表达式条件的所有文件的列表。

    files = os.listdir(path)                               
    test = re.compile("test\.py$", re.IGNORECASE)          
    files = [f for f in files if test.search(f)]

例如,您可以在不使用正则表达式的情况下执行此操作,例如对于任何表达式在结尾处返回true进行匹配的情况。 还有其他选项,例如使用filter()函数,但是如果我要选择的话,我会选择它。

埃里克·西普尔

saalon answered 2020-08-02T03:06:04Z
6 votes

您正在考虑的函数可能是operator.attrgettter。例如,获取包含每个对象的“ id”属性值的列表:

import operator
ids = map(operator.attrgetter("id"), bar)

如果要检查列表中是否包含id == 12的对象,则一种简洁有效的方法(即不会不必要地遍历整个列表)是:

any(obj.id == 12 for obj in bar)

如果要在attrgetter中使用'in',同时仍然保留列表的延迟迭代:

import operator,itertools
foo = 12
foo in itertools.imap(operator.attrgetter("id"), bar)

shang answered 2020-08-02T03:06:33Z
5 votes

我所想的可以通过列表理解来实现,但是我认为有一个函数可以以一种更加整洁的方式做到这一点。

即'bar'是对象列表,所有对象均具有'id'属性

神话般的功能方式:

foo = 12
foo in iter_attr(bar, 'id')

清单理解方式:

foo = 12
foo in [obj.id for obj in bar]

回想起来,列表理解方式还是很简洁的。

Brendan answered 2020-08-02T03:07:11Z
3 votes

如果您打算搜索任何大小合适的东西,那么最好的选择是使用字典或集合。 否则,您基本上必须遍历迭代器的每个元素,直到获得所需的元素为止。

如果这不一定是对性能敏感的代码,则列表理解方法应该起作用。 但是请注意,它效率很低,因为它遍历了迭代器的每个元素,然后再次遍历迭代器,直到找到所需的内容为止。

请记住,python具有最高效的哈希算法之一。 利用它来发挥您的优势。

Jason Baker answered 2020-08-02T03:07:40Z
0 votes

我认为:

#!/bin/python
bar in dict(Foo)

是您的想法。 当尝试查看python的字典(哈希表的python版本)中的某个键是否存在时,有两种检查方法。 首先是字典附带的baz方法,其次是上面给出的示例。 它将返回一个布尔值。

那应该回答你的问题。

现在,将话题与先前给出的列表理解答案联系在一起(稍微清楚一点),这有点偏离主题了。 列表推导从带有修饰符的基本for循环构造一个列表。 作为一个示例(稍微澄清一下),可以在列表理解中使用baz语言构造:

假设您有一个二维字典baz,而您只想要包含键baz的第二维字典。一个相对简单的方法是使用列表推导,其条件如下:

#!/bin/python
baz = dict([(key, value) for key, value in foo if bar in value])

请注意语句**末尾的baz,这是一个修改子句,它告诉列表理解仅保留那些满足条件的键值对。**在这种情况下baz是一个仅包含词典的新字典 从foo包含bar(希望在该代码示例中我什么都没错过...您可能必须看看docs.python.org教程和secnetix.de中找到的列表理解文档,这两个站点都不错 如果将来有疑问,请参考。)。

akdom answered 2020-08-02T03:08:24Z
translate from https://stackoverflow.com:/questions/683/using-in-to-match-an-attribute-of-python-objects-in-an-array