2013-03-08 54 views
0

我正在處理的屬性有時列出其元素可以是字典或進一步嵌套的對象與屬性等我想要執行一些切片,我對Python的掌握只能用什麼感覺深深地解開Pythonic。pythonic切片的嵌套屬性

我最小的代碼如下所示:

class X(object): 
    def __init__(self): 
     self.a = [] 

x=X() 
x.a.append({'key1':'v1'}) 
x.a.append({'key1':'v2'}) 
x.a.append({'key1':'v3'}) 

# this works as desired 
x.a[0]['key1'] # 'v1' 

我想執行的嵌套詞典一鍵訪問,但作出這樣的呼籲包含字典列表中的所有元素。這樣做的標準的Python的方式將是一個列表理解一拉:

[v['key1'] for v in x.a] 

然而,我的小例子,並不完全傳達我的真實世界場景中嵌套的全部範圍:類屬性列表aX可能包含對象,其屬性是對象,其屬性是字典,其鍵在迭代外部列表時要選擇它們的鍵。

# I would like something like 
useful_list = x.a[:]['key1'] # TypeError: list indices must be integers, not str 
# or even better 
cool_list = where(x.a[:]['key1'] == 'v2') # same TypeError 

如果我開始列表理解每個有趣的關鍵,它很快就不會看到所有的Pythonic。有沒有這樣做的好方法,或者我必須爲所有可能的列表和字典鍵配對編寫'getter'方法?

更新: 我一直在閱讀有關重載列表。顯然,可以混淆getitem方法,該方法用於dict的列表和鍵的索引。也許是一個遍歷列表成員的自定義類。這是開始設計的...

回答

2

所以,你想創建一個層次結構,對於不同類型的操作,意味着不同的事情,並遞歸定義。 多變性救援。

您可以覆蓋下面的__getitem__而不是我的get_items,但在您的情況下,定義非內建操作以避免冒模糊不清可能會更好。這取決於你。

class ItemsInterface(object): 
    def get_items(self, key): 
     raise NotImplementedError 

class DictItems(ItemsInterface, dict): 
    def __init__(self, *args, **kwargs): 
     dict.__init__(self, *args, **kwargs) 
    def get_items(self, key): 
     res = self[key] 
     # apply recursively 
     try: 
      res = res.get_items(key) 
     except AttributeError: 
      pass 
     return res 

class ListItems(ItemsInterface, list): 
    def __init__(self, *args, **kwargs): 
     list.__init__(self, *args, **kwargs) 
    def get_items(self, key): 
     return [ x.get_items(key) for x in self ] 

x = ListItems() 
x.append(DictItems({'key1':'v1'})) 
x.append(DictItems({'key1':'v2'})) 
x.append(DictItems({'key1':'v3'})) 
y = DictItems({'key1':'v999'}) 
x.append(ListItems([ y ])) 
x.get_items('key1') 
=> ['v1', 'v2', 'v3', ['v999']] 

當然,這種解決方案可能不是正是你需要的(你沒解釋什麼,應該怎麼做,如果密鑰丟失等) ,但你可以很容易地修改,以滿足您的需求。

該解決方案還支持ListItems作爲DictItems的值。遞歸應用get_items操作。

+1

完全按照需要工作。謝謝。它也有一個更安全的感覺,因爲使顯式更改(通過一種新方法訪問,而不是重新定義x ['key1']的作用)。尼斯 – DrSAR 2013-03-10 10:05:21

+0

很高興我能幫到你! – shx2 2013-03-10 10:25:01