2013-06-03 53 views
7

我有一個來自同一個類的實例列表,我想根據類中的屬性使我的列表不同。什麼是達到這個最pythonic方式?如何根據列表中類的屬性使Python中的列表不同?

下面是一些示例代碼:

#!/usr/bin/python 
#-*- coding:utf-8 -*- 

class MyClass(object): 
    def __init__(self, classId, tag): 
     self.classId = classId 
     self.tag = tag 

myList = [] 

myInstance1 = MyClass(1, "ABC") 
myInstance2 = MyClass(2, "DEF") 
myInstance3 = MyClass(3, "DEF") 

myList.append(myInstance1) 
myList.append(myInstance3) # note that the order is changed deliberately 
myList.append(myInstance2) 

如果我想現在是基於MyClass中的屬性之一,我通常只是通過關鍵對其進行排序排序我的列表,並使用Lambda表達式設定的關鍵 - 這樣的:

myList.sort(key=lambda x: x.classId) 
for x in myList: 
    print x.classId 

$ python ./test.py 
1 
2 
3 

是否有可能採用類似的方法(拉姆達,地圖或相似),使基於「標籤」屬性列表中不同?另外,如果這是可能的話,那麼它是根據該列表中的類的屬性使清單不同的最「pythonic」方式嗎?

我已經嘗試過對此事的主題搜索既SO和谷歌,但我發現處理的簡單列表僅包含一個數值,而不是一個自定義對象的結果..

回答

6

假設你財產希望加鍵是不可變的,你可以使用的字典:

d = {} 
for x in xs: 
    d[x.tag] = x 

現在d將包含每tag值單x;您可以使用d.values()d.itervalues()獲取xs

注意:這裏最後一個匹配項獲勝;獲得第一個勝利,反向迭代。

+0

一旦您還可以使用過濾器()(http://docs.python.org/2/library/functions。 html#filter),由於inline for-loop,它應該稍微快一點。 – pypat

+0

謝謝。這(使用字典)的作品,但它是實現它的「最好」的方式嗎? pypat提出的解決方案似乎更加pythonic。 – v3gard

+1

@pypat:我想你可以通過謂詞爲字典添加先前未知的值,或者實際上只是一個集合:'s = set()',然後'filter(lambda x:False if x.tag in s else (s.add(x.tag)或True),myList)'。感謝您的建議!儘管如此,基於'for-and-dict-based'的版本讓我感覺更簡單,所以我在切換之前進行基準測試。 –

9

您可以使用python dict comprehension

{x.tag: x for x in myList}.values() 

對於示例:

>>> class MyClass(object): 
...  def __init__(self, classId, tag): 
...   self.classId = classId 
...   self.tag = tag 
... 
>>> myList = [MyClass(1, "ABC"), MyClass(2, "DEF"), MyClass(3, "DEF")] 
>>> uniqList = {x.tag: x for x in myList}.values() 
>>> print [x.classId for x in uniqList] 
[1, 3] 
相關問題