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

tqui 发布于 2018-02-04 arrays 最后更新 2018-02-04 01:08 975 浏览

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

foo in iter_attr(array of python objects, attribute name)
我查看了文档,但这种东西不属于任何明显的列表标题
已邀请:

znemo

赞同来自:

不,你不是在做梦。 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()函数,但如果我要选择,我会去这个。 Eric Sipple

oillo

赞同来自:

我认为:

#!/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 tutorialssecnetix.de中找到列表理解文档,如果将来有问题,这两个站点都是很好的参考)。

vomnis

赞同来自:

你是否想要获得具有特定属性的对象列表?如果是这样,list comprehension是正确的方法。

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

tqui

赞同来自:

我所想的可以通过列表理解来实现,但是我认为有一个函数可以稍微整理一下。 即“酒吧”是对象的列表,所有对象都具有属性“id” 神话功能方式:

foo = 12
foo in iter_attr(bar, 'id')
列表理解方式:
foo = 12
foo in [obj.id for obj in bar]
回想起来,列表的理解方式是非常整齐的。

set

赞同来自:

你总是可以自己写一个:

def iterattr(iterator, attributename):
    for obj in iterator:
        yield getattr(obj, attributename)
将与迭代的任何东西一起工作,无论是元组,列表还是其他任何东西。 我喜欢python,它使得这样的东西非常简单,没有必要的麻烦,使用这样的东西是非常优雅的。

aet

赞同来自:

如果你打算搜索任何规模偏大的东西,你最好的办法是使用字典或一套。否则,你基本上必须遍历迭代器的每个元素,直到你到达你想要的。 如果这不一定是性能敏感的代码,那么列表理解的方式应该工作。但是请注意,这是相当低效率的,因为它遍历了迭代器的每个元素,然后再次返回,直到找到想要的结果。 请记住,python有一个最有效的哈希算法。使用它你的优势。

snihil

赞同来自:

使用列表理解将建立一个临时列表,如果被搜索的序列很大,这个列表可能会吃掉所有的记忆。即使序列不是很大,构建列表意味着在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'))

nautem

赞同来自:

您正在考虑的功能可能是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)