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