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

我不记得我是不是在做梦,但我似乎记得有一个function,

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

我查看了文档,但这种东西不属于任何明显的列表标题

使用列表理解将build立一个临时列表,如果被search的序列很大,这个列表可能会吃掉所有的记忆。 即使序列不大,构build列表意味着迭代整个序列,然后才能开始search。

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

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

现在,只要obj.id == 12附近的bar开始,search将会很快,即使bar无限长。

正如@Mattbuild议的那样,如果bar任何对象可能缺lessid属性,则使用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,它使得这样的东西非常简单,没有必要的麻烦,使用这样的东西是非常优雅的。

你正在想的function可能是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) 

不,你不是在做梦。 Python有一个非常优秀的列表理解系统,可以让你非常优雅地操作列表,而且根据你想要完成的事情,这可以通过几种方法来完成。 实质上,你在做的是说“对于列表中的项目,如果criteria.matches”,并且你可以迭代通过结果或转储结果到一个新的列表。

我将在这里讨论Dive Into Python的一个例子,因为它非常优雅,比我更聪明。 在这里,他们获取目录中的文件列表,然后过滤符合正则expression式条件的所有文件的列表。

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

你可以在没有正则expression式的情况下执行这个操作,例如你的expression式在结尾返回true表示匹配。 还有其他的select,如使用filter()函数,但如果我要select,我会去这个。

Eric Sipple

我所想的可以通过列表理解来实现,但是我认为有一个函数可以稍微整理一下。

即“酒吧”是一个对象的列表,所有的对象具有属性“ID”

神话function方式:

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

列表理解方式:

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

回想起来,列表的理解方式是非常整齐的。

如果你打算search任何规模偏大的东西,你最好的办法是使用字典或一套。 否则,你基本上必须遍历迭代器的每个元素,直到你到达你想要的。

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

请记住,python有一个最有效的哈希algorithm。 使用它你的优势。

我认为:

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

是你在想什么。 当试图查看某个关键字是否存在于python(python版本的哈希表)中时,有两种方法可以检查。 首先是连接到字典的has_key()方法,其次是上面给出的例子。 它将返回一个布尔值。

这应该回答你的问题。

现在有一个小题目把这个问题和以前给出的列表理解答案联系起来(更清楚些)。 列表理解从一个基本的循环修饰符构造一个列表。 作为一个例子(稍微澄清一点),一种在列表理解中使用in dict语言结构的方法:

假设你有一个二维字典foo而你只想要包含关键bar二维字典。 这样做的一个相对直接的方法是使用一个有条件的列表理解 ,如下所示:

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

注意在语句**结尾的if bar in valueif bar in value ,这是一个修改子句,它告诉列表理解只保留那些符合条件的键值对**在这种情况下, baz是一个新的字典,它包含只有包含bar的foo的字典(希望我没有错过那个代码示例中的任何东西…你可能不得不看看docs.python.org教程和secnetix.de中的列表理解文档,如果你将来有问题,网站是很好的参考。)