我很难理解如何构建一个从内到外在列表中的列表上工作的函数(我想你可能很难描述它)。
我正在尝试动态转换像
这样的列表res = SomeDjangoQuerySet
x = ['neighborhood', ['city', ['metro', 'metro']]]
成:
getattr(getattr(getattr(getattr(res, 'neighborhood'), 'city'), 'metro'), 'metro')
AKA:
getattr(getattr(getattr(getattr(res, x[0]), x[1][0]), x[1][1][0]), x[1][1][1])
基本上,第一个值将始终是一个字符串,第二个值将是字符串或列表。每个列表都将遵循此模式(字符串,字符串或列表)。列表中列表的深度是不确定的。 getattr()的最里面的第一个值将是一个外部变量(在这种情况下为“res”)。有什么建议吗?
答案 0 :(得分:3)
这听起来像递归和迭代可能是有用的。这样做你想要的吗?
def flatten(data):
res = []
if hasattr(data, '__iter__'):
for el in data:
res.extend(flatten(el))
else:
res.append(data)
return res
reduce(getattr, flatten(x), res)
答案 1 :(得分:1)
def nestattr(x, y):
if isinstance(y, str):
return getattr(x, y)
elif isinstance(y, list):
return nestattr(getattr(x, y[0]), y[1])
nestattr(res, x)
所以你从列表中的第一个字符串开始,你有(1)查询的getattr
和(2)该字符串。然后你使用该列表的其余部分递归,如果它是一个字符串,你只需要{1}}(1)上一个getattr
的结果和(2)这个字符串。否则,如果它仍然是列表,则重复。我想这就是你要找的东西?如果我错了,请纠正我。
答案 2 :(得分:1)
我最后花了一些时间学习递归,发现这是最简单的解决方案(尽管,David Zwicker也提供了一个可行的解决方案)。
def recursion(a, b):
if type(b) is list:
return recursion(getattr(a, b[0]), b[1])
else:
return getattr(a, b)
recursion(res, x)