首页 / 知识

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

2023-04-11 13:57:00

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

Using 'in' to match an attribute of Python objects in an array

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

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

我看了看文档,但是这种事情并不属于列出的任何明显的标题


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

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

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

现在,只要obj.id == 12靠近bar的开头,即使bar无限长,搜索也将很快。

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

1
2
foo = 12
foo in (obj.id for obj in bar if hasattr(obj, 'id'))

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

1
result = [obj for obj in listOfObjs if hasattr(obj, 'attributeName')]


您总是可以自己写一个:

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

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

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


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

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

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

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

埃里克·西普尔


您正在考虑的功能可能是operator.attrgettter。例如,要获取一个包含每个对象的" id"属性值的列表:

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

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

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

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

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


我所想的可以使用列表理解来实现,但是我认为有一个函数可以稍微整洁地完成此任务。

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

神话般的功能方式:

1
2
foo = 12
foo in iterattr(bar, 'id')

清单理解方式:

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

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


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

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

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


我认为:

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

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

那应该回答你的问题。

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

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

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

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


对象属性执行操作

最新内容

相关内容

热门文章

推荐文章

标签云

猜你喜欢