繁体   English   中英

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

[英]Using 'in' to match an attribute of Python objects in an array

我不记得我是否在做梦,但我似乎记得有一个功能允许类似的东西,

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

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

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

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

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

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

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

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

您是否希望获得具有特定属性的对象列表? 如果是这样, 列表理解是正确的方法。

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

你总是可以自己写一个:

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

将适用于任何迭代的东西,无论是元组、列表还是其他任何东西。

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

不,你不是在做梦。 Python 有一个非常出色的列表理解系统,可以让您非常优雅地操作列表,并且根据您想要完成的确切内容,这可以通过几种方式完成。 从本质上讲,您正在做的是说“对于列表中的项目,如果criteria.matches”,然后您可以遍历结果或将结果转储到新列表中。

我将在这里引用 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() 函数,但如果我要选择,我会选择这个。

埃里克·西普尔

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

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

如果您想检查列表是否包含一个 id == 12 的对象,那么一种简洁高效(即不会不必要地迭代整个列表)的方法是:

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

如果您想将 'in' 与 attrgetter 一起使用,同时仍保留列表的惰性迭代:

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

使用列表推导式可以实现我的想法,但我认为有一个函数可以以更简洁的方式完成此操作。

即 'bar' 是一个对象列表,所有这些对象都具有属性 'id'

神话般的功能方式:

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

列表理解方式:

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

回想起来,无论如何,列表理解方式非常简洁。

如果您打算搜索任何大小合适的东西,最好的办法是使用字典或集合。 否则,您基本上必须遍历迭代器的每个元素,直到找到您想要的元素。

如果这不一定是性能敏感的代码,那么列表理解方式应该可以工作。 但请注意,它的效率相当低,因为它遍历迭代器的每个元素,然后再次返回,直到找到它想要的元素。

请记住,python 拥有最高效的散列算法之一。 充分利用它。

我认为:

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

是你在想什么。 当尝试查看 python 中的字典中是否存在某个键时(哈希表的 python 版本),有两种方法可以检查。 第一个是附加到字典的has_key()方法,第二个是上面给出的例子。 它将返回一个布尔值。

那应该回答你的问题。

现在有点偏离主题,将其与之前给出的列表理解答案联系起来(为了更清楚一点)。 列表推导式从带有修饰符的基本for 循环构造一个列表。 作为一个例子(稍微澄清一下),一种在列表理解中使用in dict语言结构的方法:

假设您有一个二维字典foo并且您只想要包含键bar的第二维字典。 一种相对直接的方法是使用带有条件的列表推导式,如下所示:

#!/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中的列表理解文档,两者都是如果您将来有问题,网站是很好的参考。)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM