[英]Iterate over nested lists, tuples and dictionaries
I've another question to the thematic of Iterate over nested lists and dictionaries . 我对嵌套列表和字典的迭代主题提出了另一个问题。
I need some extended functionality to the topic of the link above. 我需要一些上述链接主题的扩展功能。 The iterable element now also contains tuples .
iterable元素现在还包含元组 。 Also integers in tuples need to be converted to a hex string.
元组中的整数也需要转换为十六进制字符串。 Therefor I tried with following code, to convert the tuples to lists.
因此,我尝试使用以下代码,将元组转换为列表。
for path, value in objwalk(element):
if isinstance(value, tuple):
parent = element
for step in path[:-1]:
parent = parent[step]
parent[path[-1]] = list(value)
But my problem is, that tuples in tuples are not converted. 但我的问题是,元组中的元组没有被转换。 How can I convert "sub-tuples" to lists in an elegant way?
如何以优雅的方式将“子元组”转换为列表?
Best regards wewa 最好的问候wewa
PS: I created a new topic, because the other-one is fixed for me. PS:我创建了一个新主题,因为另一个是为我修复的。
In this case, it would be easier to handle tuples directly in the objwalk
structure traverser. 在这种情况下,直接在
objwalk
结构遍历器中处理元组会更容易。 Here is a modified version that converts tuples to lists before traversing over them to find nested elements: 这是一个修改过的版本,它在遍历它们以查找嵌套元素之前将元组转换为列表:
def objwalk(obj, path=(), memo=None):
if memo is None:
memo = set()
iterator = None
if isinstance(obj, dict):
iterator = iteritems
elif isinstance(obj, (list, set)) and not isinstance(obj, string_types):
iterator = enumerate
if iterator:
if id(obj) not in memo:
memo.add(id(obj))
for path_component, value in iterator(obj):
if isinstance(value, tuple):
obj[path_component] = value = list(value)
for result in objwalk(value, path + (path_component,), memo):
yield result
memo.remove(id(obj))
else:
yield path, obj
Using a slightly modified example from your previous question, and the same hex
solution I gave you in that question: 使用上一个问题中稍微修改过的示例,以及我在这个问题中给出的相同的
hex
解决方案:
>>> element = {'Request': (16, 2), 'Params': ('Typetext', [16, 2], 2), 'Service': 'Servicetext', 'Responses': ({'State': 'Positive', 'PDU': [80, 2, 0]}, {})}
>>> for path, value in objwalk(element):
... if isinstance(value, int):
... parent = element
... for step in path[:-1]:
... parent = parent[step]
... parent[path[-1]] = hex(value)
...
>>> element
{'Params': ['Typetext', ['0x10', '0x2'], '0x2'], 'Request': ['0x10', '0x2'], 'Responses': [{'State': 'Positive', 'PDU': ['0x50', '0x2', '0x0']}, {}], 'Service': 'Servicetext'}
If the overhead of creating new objects is not an issue, I think it's pretty clear to go with: 如果创建新对象的开销不是问题,我认为很明显:
def transform(obj):
_type = type(obj)
if _type == tuple: _type = list
rslt = _type()
if isinstance(obj, dict):
for k, v in obj.iteritems():
rslt[k] = transform(v)
elif isinstance(obj, (list, tuple)):
for x in obj:
rslt.append(transform(x))
elif isinstance(obj, set):
for x in obj:
rslt.add(transform(x))
elif isinstance(obj, (int, long)):
rslt = hex(obj)
else:
rslt = obj
return rslt
element = transform(element)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.