我正在寻找一种快速,干净和pythonic的方式来切割自定义对象,同时在操作后保留它们的类型。
为了给你一些上下文,我必须处理很多半非结构化数据并处理它我使用字典列表。为了简化某些操作,我创建了一个“ld”对象,它继承自“list”。在其众多功能中,它检查数据是否以正确的格式提供。让我们通过说它确保列表的所有条目都是包含一些键“a”的字典来简化它,如下所示:
class ld( list):
def __init__(self, x):
list.__init__(self, x)
self.__init_check()
def __init_check(self):
for record in self:
if isinstance( record, dict) and "a" in record:
pass
else:
raise TypeError("not all entries are dictionaries or have the key 'a'")
return
当数据符合要求并且初始化ld:
时,此行为正确tt = ld( [{"a": 1, "b":2}, {"a":4}, {"a":6, "c":67}])
type( tt)
当数据不正确时,它也是正确的:
ld( [{"w":1}])
ld( [1,2,3])
然而,当我继续切片对象时会出现问题:
type( tt[:2])
tt [:2]是一个列表,不再是我在完全成熟的ld对象中创建的所有方法和属性。我可以将切片重新转换为ld,但这意味着它必须再次完成整个初始数据检查过程,从而大大减慢计算速度。
这是我提出的加速解决方案的解决方案:
class ld( list):
def __init__(self, x, safe=True):
list.__init__(self, x)
self.__init_check( safe)
def __init_check(self, is_safe):
if not is_safe:
return
for record in self:
if isinstance( record, dict) and "a" in record:
pass
else:
raise TypeError("not all entries are dictionaries or have the key 'a'")
return
def __getslice__(self, i, j):
return ld( list.__getslice__( self, i, j), safe=False)
是否有一种更干净,更灵巧的方式? 在此先感谢您的帮助。
答案 0 :(得分:0)
我不认为继承list
来验证其内容的形状或类型通常是正确的方法。 list
明确地不关心它的内容,并且实现一个类,其构造函数行为根据传递给它的标志而变化是混乱的。如果需要一个验证输入的构造函数,只需在返回列表的函数中执行检查逻辑。
def make_verified_list(items):
"""
:type items: list[object]
:rtype: list[dict]
"""
new_list = []
for item in items:
if not verify_item(item):
raise InvalidItemError(item)
new_list.append(item)
return new_list
def verify_item(item):
"""
:type item: object
:rtype: bool
"""
return isinstance(item, dict) and "a" in item
采用这种方法,你不会发现自己在努力应对核心数据结构的行为。