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

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

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

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

0
额外 编辑
意见: 1

10 答案

至于编写一个功能,我已经概述了如何使用事件接收器来完成该功能 here

您只需要替换代码以添加事件接收器和代码以添加权限级别和组。另外,在帖子的底部,我将讨论如何将其装订到特定的网站定义。

权限级别在api中称为角色。您需要创建新的 SPRoleDefinition ,配置名称和basepermissions,然后将其添加到SPWeb.RoleDefinitions集合中。

组在api中称为组。您将需要调用SPWeb.Groups.Add来创建一个组。

我希望这一切都有道理。

1
额外

我所想的可以通过列表解析来实现,但我认为有一个函数以稍微整洁的方式做到了这一点。

即“酒吧”是对象的列表,所有对象都具有属性“id”

神话的功能方式:

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

列表理解方式:

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

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

0
额外

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

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

  files = os.listdir(path)
    test = re.compile(“test \ .py $”,re.IGNORECASE)
    files = [f for f in file if test.search(f)]
</代码> 

你可以在没有正则表达式的情况下做到这一点,例如,你的表达式最后返回true表示匹配。还有其他的选择,比如使用filter()函数,但是如果我要选择,我会选择这个。

埃里克希普尔

0
额外

我认为:

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

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

这应该回答你的问题。

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

假设您有一个二维词典 foo ,并且您只需要包含关键 bar 的第二维词典。一个相对简单的方法是使用带有条件的列表理解,如下所示:

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

在语句**的末尾注意 if value 中的 ,这是一个修改子句,它告诉列表理解只保留那些在这种情况下, baz 是一个新的字典,它只包含foo中包含bar的字典(希望我没有错过该代码示例中的任何内容......您可能需要查看 docs.python.org教程secnetix.de ,如果你将来有问题,这两个网站都是很好的参考。)。

0
额外

如果你打算搜索任何尺寸偏小的东西,最好的办法就是使用字典或一套。否则,你基本上必须遍历迭代器的每个元素,直到找到你想要的。

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

请记住,python具有最高效的哈希算法之一。使用它你的优势。

0
额外

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

使用列表理解将建立一个临时列表,如果被搜索的序列很大,它可能会吃掉你所有的记忆。即使序列不大,构建列表意味着在中的开始搜索之前遍历整个序列。

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

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'))
0
额外

你是否在寻找具有特定属性的对象列表?如果是这样,列表理解是正确的方法。

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

你总是可以自己写一个:

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

将与迭代的任何东西一起工作,无论是元组,列表还是其他任何东西。

我喜欢python,它使得这些东西非常简单,没有必要的麻烦,而且在使用这种东西时非常优雅。

0
额外