我正在开发这个Python项目,我多次遇到这种情况,我想知道是否有更好的方法。
有一个类实例列表。列表的某些部分是空的(填充None
)。
这是一个示例列表。
ins_list = [ins_1, ins_2, None, ins_3, None]
我必须在整个程序流程中做一些确认。我需要控制这些实例的属性。但是只给出了从列表中选择实例的索引,它可能是空元素之一。调用属性时会出错。这是一个示例程序流程。
ind = 2
if ins_list[ind].some_attribute == "thing":
# This would give error when empty element is selected.
我通过使用
来解决这个问题if ins_list[ind]:
if ins_list[ind].some_attribute == "thing":
# This works
我可以使用它。但是程序很长,我应用了数百次。是否有更简单,更好的方法,这意味着我正在生成reduntant代码并无缘无故地增加缩进级别。我想知道是否有这样的解决方案。
答案 0 :(得分:0)
有以下两种选择:
使用字典:
另一种方法是使用dictionary
代替。因此,您可以在列表填充元素后创建字典。字典的键将是列表的值,作为值,您可以使用非None和" No_attr"的元素的属性。对于那些没有。 (注意:请记住,python词典不支持重复键,这就是为什么我建议在下面存储作为键列表索引,否则你将不得不找到一种方法使密钥不同)
例如,列表如下:
l = [item1,item2,None,item4]
你可以创建一个字典:
d = {item1:"thing1", item2:"thing2", None:"No_attr", item3:"thing3"}
因此,每当您需要进行检查时,您不必检查两个条件,但您只能检查值,例如:
if d.values()[your_index]=="thing":
此方法的唯一缺点是标准的python词典本质上无序,这使得通过索引访问字典值有时会有点危险 - 你必须小心不要改变字典的形式排列。
现在,如果您想确保索引保持稳定,那么您必须以某种方式存储它,例如选择字典的键索引,因为您已经存储了项目的属性 - 但,这是您必须决定的,并且在很大程度上取决于项目的体系结构。
使用列表:
在使用list
的方式时,我认为没有办法避免你的if语句 - 实际上也不错。也许使用and
运算符,因为在另一个答案中已经提到过,但我认为这无论如何都没有任何区别。
,如果您想使用第一种方法:
if ins_list[ind].some_attribute == "thing":
您可以尝试使用和例外捕获器:
try:
if ins_list[ind].some_attribute == "thing":
#do something
except:
#an error occured
pass
答案 1 :(得分:0)
使用布尔运算符and
。
if ins_list[ind] and ins_list[ind].some_attribute == "thing":
# Code
答案 2 :(得分:0)
正如编码人员提议的那样,您可以从列表中删除None,或者使用词典,以避免必须为每个索引创建条目。
我想提出另一种方法:你可以创建一个虚拟类并用它替换None。这样,如果设置属性,则不会出现错误:
class dummy:
def __nonzero__(self):
return False
def __setattr__(self, k, v):
return
mydummy = dummy()
mylist = [ins_1, ins_2, mydummy, ins_3, mydummy]
设置属性
时,不会将任何内容存储到虚拟实例中修改强>
如果无法选择原始列表的内容,则此类可以提供帮助:
class PickyList(list):
def __init__(self, iterable, dummyval):
self.dummy = dummyval
return super(PickyList, self).__init__(iterable)
def __getitem__(self, k):
v = super(PickyList, self).__getitem__(k)
return (self.dummy if v is None else v)
mylist = PickyList(ins_list, mydummy)
答案 3 :(得分:0)
在这种情况下,我会使用try-except语句,因为EAFP (更容易要求原谅而不是权限)。它不会缩短你的代码,但在检查有效属性时,它是一种更加Pythonic的代码编码方式。这样你就不会打破DRY (不要自己重拍)。
try:
if ins_list[ind].some_attribute == "thing":
# do_something()
except AttributeError:
# do_something_else()