【发布时间】:2010-09-05 06:24:51
【问题描述】:
我不记得我是不是在做梦,但我似乎记得有一个函数允许类似,
foo in iter_attr(array of python objects, attribute name)
我查看了文档,但这类内容不属于任何明显列出的标题
【问题讨论】:
我不记得我是不是在做梦,但我似乎记得有一个函数允许类似,
foo in iter_attr(array of python objects, attribute name)
我查看了文档,但这类内容不属于任何明显列出的标题
【问题讨论】:
使用列表推导会构建一个临时列表,如果要搜索的序列很大,它可能会吃掉你所有的记忆。即使序列不大,构建列表也意味着在in 开始搜索之前遍历整个序列。
使用生成器表达式可以避免临时列表:
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'))
【讨论】:
您是否正在寻找具有特定属性的对象列表?如果是这样,list comprehension 是正确的做法。
result = [obj for obj in listOfObjs if hasattr(obj, 'attributeName')]
【讨论】:
你总是可以自己写一个:
def iterattr(iterator, attributename):
for obj in iterator:
yield getattr(obj, attributename)
适用于任何迭代的东西,无论是元组、列表还是其他任何东西。
我喜欢 python,它使这样的东西变得非常简单,而且没有比必要的麻烦,而且在使用这样的东西时非常优雅。
【讨论】:
不,你不是在做梦。 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() 函数,但如果我要选择,我会选择这个。
埃里克·斯普尔
【讨论】:
你想到的函数大概是operator.attrgettter。例如,要获取包含每个对象的“id”属性值的列表:
import operator
ids = map(operator.attrgetter("id"), bar)
如果您想检查列表是否包含 id == 12 的对象,那么一种简洁高效(即不会不必要地迭代整个列表)的方法是:
any(obj.id == 12 for obj in bar)
如果您想将 'in' 与 attrgetter 一起使用,同时仍保留列表的惰性迭代:
import operator,itertools
foo = 12
foo in itertools.imap(operator.attrgetter("id"), bar)
【讨论】:
我的想法可以使用列表推导来实现,但我认为有一个函数可以以稍微简洁的方式做到这一点。
即'bar' 是一个对象列表,所有对象都具有 'id' 属性
神话般的功能方式:
foo = 12
foo in iter_attr(bar, 'id')
列表理解方式:
foo = 12
foo in [obj.id for obj in bar]
回想起来,列表理解方式还是很简洁的。
【讨论】:
如果您打算搜索任何大小合适的东西,最好的选择是使用字典或集合。否则,您基本上必须遍历迭代器的每个元素,直到找到您想要的那个。
如果这不一定是性能敏感代码,那么列表理解方式应该可以工作。但请注意,它的效率相当低,因为它会遍历迭代器的每个元素,然后再次返回,直到找到所需的内容。
请记住,python 拥有最有效的散列算法之一。充分利用它。
【讨论】:
我认为:
#!/bin/python
bar in dict(Foo)
是你所想的。当试图查看某个键是否存在于 python(python 的哈希表版本)的字典中时,有两种检查方法。第一个是附加到字典的 has_key() 方法,第二个是上面给出的示例。它将返回一个布尔值。
这应该可以回答你的问题。
现在有点偏离主题,将其与之前给出的列表理解答案联系起来(为了更清楚一点)。 List Comprehensions 从带有修饰符的基本 for 循环 构造一个列表。作为一个例子(稍微澄清一下),一种在列表理解中使用in dict语言结构的方法:
假设您有一个二维字典 foo,而您只想要包含键 bar 的二维字典。一个相对简单的方法是使用 list comprehension 和如下条件:
#!/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 tutorials 和secnetix.de 中的列表理解文档,如果您将来有问题,这两个站点都是很好的参考。)。
【讨论】:
/bin?