好的,所以我有一个包含三个值(code, value, unit)
当我要使用它时,我需要检查一个值是一个str,一个列表还是一个矩阵。 (或检查是否列表,然后再检查是否列表)
我的问题是我应该这样做,还是有更好的方法?
for code, value, unit in tuples:
if isinstance(value, str):
# Do for this item
elif isinstance(value, collections.Iterable):
# Do for each item
for x in value:
if isinstance(x, str):
# Do for this item
elif isinstance(x, collections.Iterable):
# Do for each item
for x in value:
# ...
else:
raise Exception
else:
raise Exception
答案 0 :(得分:3)
最好的解决方案是避免像这样混合类型,但是如果你坚持使用它,那么你写的就好了,除了我只检查str
实例。如果它不是一个字符串或一个可迭代的,那么无论如何你都会得到一个更合适的例外,所以不需要自己做。
for (code,value,unit) in tuples:
if isinstance(value,str):
#Do for this item
else:
#Do for each item
for x in value:
if isinstance(value,str):
#Do for this item
else:
#Do for each item
for x in value:
答案 1 :(得分:2)
这有效,但每次拨打isinstance
时,您都应该问自己“我可以向value
添加方法吗?”这会将代码更改为:
for (code,value,unit) in tuples:
value.doSomething(code, unit)
要实现此目的,您必须将str
之类的类型和实现doSomething()
答案 2 :(得分:2)
您的方法的替代方法是将此代码分解为更通用的生成器函数(假设Python 2.x):
def flatten(x):
if isinstance(x, basestring):
yield x
else:
for y in x:
for z in flatten(y):
yield y
(这也包含Duncan's answer中建议和解释的简化。)
现在,您的代码变得非常简单易读:
for code, value, unit in tuples:
for v in flatten(value):
# whatever
将代码分解也有助于在代码中的几个位置处理此数据结构。
答案 3 :(得分:1)
只需使用元组并捕获任何异常。在你跳之前不要看:)
答案 4 :(得分:0)
递归会有所帮助。
def processvalue(value):
if isinstance(value, list): # string is type Iterable (thanks @sven)
for x in value:
processvalue(value)
else:
# Do your processing of string or matrices or whatever.
# Test each the value in each tuple.
for (code, value, unit) in tuples:
processvalue(value)
这是处理嵌套结构的一种更简洁的方法,也可以让你处理abitrary深度。