2013-03-08 35 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