使用''in''匹配数组中Python对象的属性
我不记得我是否在做梦,但我似乎还记得有一个函数可以执行以下操作:
foo in iter_attr(array of python objects, attribute name)
我看了看文档,但是这种事情不会落在任何明显列出的标题下
解决方案:
不,你不是在做梦。 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()函数,但是如果我要选择的话,我会选择它。
埃里克·西普尔(Eric Sipple)
我认为:
#!/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,如果我们将来有任何疑问,这两个站点都是不错的参考。)
我们是否正在寻找具有特定属性的对象列表?如果是这样,列表理解是执行此操作的正确方法。
result = [obj for obj in listOfObjs if hasattr(obj, 'attributeName')]
我所想的可以通过列表理解来实现,但是我认为有一个函数可以稍微整洁地做到这一点。
即''bar''是对象列表,所有对象均具有''id''属性
神话般的功能方式:
foo = 12 foo in iter_attr(bar, 'id')
清单理解方式:
foo = 12 foo in [obj.id for obj in bar]
回想起来,列表理解方式还是很简洁的。
我们总是可以自己写一个:
def iterattr(iterator, attributename): for obj in iterator: yield getattr(obj, attributename)
可以处理任何迭代的对象,无论是元组,列表还是其他。
我喜欢python,它使这样的事情变得非常简单,并且没有不必要的麻烦,而在使用中,这样的事情非常优雅。
如果我们打算搜索任何大小合适的东西,那么最好的选择是使用字典或者集合。否则,我们基本上必须遍历迭代器的每个元素,直到获得所需的元素为止。
如果这不一定是对性能敏感的代码,则列表理解方法应该起作用。但是请注意,它效率很低,因为它遍历了迭代器的每个元素,然后再次遍历迭代器,直到找到所需的内容为止。
请记住,python具有最高效的哈希算法之一。利用它来发挥优势。
使用列表推导会建立一个临时列表,如果要搜索的序列很大,则该列表可能会占用所有内存。即使序列不大,构建列表也意味着在" in"开始搜索之前对整个序列进行迭代。
通过使用生成器表达式可以避免使用临时列表:
foo = 12 foo in (obj.id for obj in bar)
现在,只要在" bar"开始处附近有" obj.id == 12",即使" bar"无限长,搜索也将很快。
正如@Matt所建议的,如果bar
中的任何对象都可能缺少id
属性,则使用hasattr
是个好主意:
foo = 12 foo in (obj.id for obj in bar if hasattr(obj, 'id'))