我不记得我是不是在做梦,但我似乎记得有一个功能允许类似的东西, 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无限长。 hasattr正如@Matt 所建议的那样,如果其中的任何对象bar可能缺少属性,那么使用它是个好主意id: 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,它使像这样的东西变得非常简单,而且除了必要之外没有麻烦,而且像这样的东西在使用中非常优雅。
不,你不是在做梦。Python 有一个非常出色的列表理解系统,可以让您非常优雅地操作列表,并且根据您想要完成的具体目标,可以通过几种方式完成。本质上,您正在做的是说“如果 criteria.matches,则列表中的项目”,您可以从中迭代结果或将结果转储到新列表中。 I'm going to crib an example from Dive Into Python here, because it's pretty elegant and they're smarter than I am. Here they're getting a list of files in a directory, then filtering the list for all files that match a regular expression criteria. files = os.listdir(path) test = re.compile("test\.py$", re.IGNORECASE) files = [f for f in files if test.search(f)] You could do this without regular expressions, for your example, for anything where your expression at the end returns true for a match. There are other options like using the filter() function, but if I were going to choose, I'd go with this. Eric Sipple
The function you are thinking of is probably operator.attrgettter. For example, to get a list that contains the value of each object's "id" attribute: import operator ids = map(operator.attrgetter("id"), bar) If you want to check whether the list contains an object with an id == 12, then a neat and efficient (i.e. doesn't iterate the whole list unnecessarily) way to do it is: any(obj.id == 12 for obj in bar) If you want to use 'in' with attrgetter, while still retaining lazy iteration of the list: import operator,itertools foo = 12 foo in itertools.imap(operator.attrgetter("id"), bar)
What I was thinking of can be achieved using list comprehensions, but I thought that there was a function that did this in a slightly neater way. i.e. 'bar' is a list of objects, all of which have the attribute 'id' The mythical functional way: foo = 12 foo in iter_attr(bar, 'id') The list comprehension way: foo = 12 foo in [obj.id for obj in bar] In retrospect the list comprehension way is pretty neat anyway.
If you plan on searching anything of remotely decent size, your best bet is going to be to use a dictionary or a set. Otherwise, you basically have to iterate through every element of the iterator until you get to the one you want. If this isn't necessarily performance sensitive code, then the list comprehension way should work. But note that it is fairly inefficient because it goes over every element of the iterator and then goes BACK over it again until it finds what it wants. Remember, python has one of the most efficient hashing algorithms around. Use it to your advantage.
I think: #!/bin/python bar in dict(Foo) Is what you are thinking of. When trying to see if a certain key exists within a dictionary in python (python's version of a hash table) there are two ways to check. First is the has_key() method attached to the dictionary and second is the example given above. It will return a boolean value. That should answer your question. And now a little off topic to tie this in to the list comprehension answer previously given (for a bit more clarity). List Comprehensions construct a list from a basic for loop with modifiers. As an example (to clarify slightly), a way to use the in dict language construct in a list comprehension: Say you have a two dimensional dictionary foo and you only want the second dimension dictionaries which contain the key bar. A relatively straightforward way to do so would be to use a list comprehension with a conditional as follows: #!/bin/python baz = dict([(key, value) for key, value in foo if bar in value]) Note the if bar in value at the end of the statement**, this is a modifying clause which tells the list comprehension to only keep those key-value pairs which meet the conditional.** In this case baz is a new dictionary which contains only the dictionaries from foo which contain bar (Hopefully I didn't miss anything in that code example... you may have to take a look at the list comprehension documentation found in docs.python.org tutorials and at secnetix.de, both sites are good references if you have questions in the future.).