簡體   English   中英

使用“in”匹配數組中 Python 對象的屬性

[英]Using 'in' to match an attribute of Python objects in an array

我不記得我是否在做夢,但我似乎記得有一個功能允許類似的東西,

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'))

您是否希望獲得具有特定屬性的對象列表? 如果是這樣, 列表理解是正確的方法。

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”,然后您可以遍歷結果或將結果轉儲到新列表中。

我將在這里引用 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()方法,第二個是上面給出的例子。 它將返回一個布爾值。

那應該回答你的問題。

現在有點偏離主題,將其與之前給出的列表理解答案聯系起來(為了更清楚一點)。 列表推導式從帶有修飾符的基本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 教程secnetix.de中的列表理解文檔,兩者都是如果您將來有問題,網站是很好的參考。)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM