具有深度值的镜像列表,到嵌套列表 ~ Python
Mirroring List with Depth Values, to Nested List ~ Python
我打算自动化装配过程,并尝试构建 C4D Python 脚本。我正在尝试将基于深度值的列表镜像到嵌套列表。
假设我们有一个包含深度值的列表:
depth_list = [[0,'Hips'],[1,'Spine'],[2,'Spine1'],[3,'Spine2'],[4,'Neck'],[5,'Head'],[6,'HeadTop_End'],[4,'LeftShoulder']]
我们希望这个成为一个基于深度值的嵌套联合列表:
joint_list = [['Hips',['Spine',['Spine1',['Spine2',['Neck',['Head',['HeadTop_End']]],['LefShoulder']]]]]]
我已经走到这一步了:
for joint in depth_list:
this_depth = joint[0]
try:
joint_list.append(0)
except IndexError:
pass
这是我从 C4D 树导出脚本中得到的原始数据
0 Hips
1 Spine
2 Spine1
3 Spine2
4 Neck
5 Head
6 HeadTop_End
4 LeftShoulder
这是一张图片:
[![enter image description here][1]][1]
祝大家一千万快乐!
你可以试试这个代码:
depth_list = [[0,'Hips'],[1,'Spine'],[2,'Spine1'],[3,'Spine2'],[4,'Neck'],[5,'Head'],[6,'HeadTop_End'],[4,'LeftShoulder']]
result = []
current_list = None
current_item = []
current_level = 0
level_dict = {}
for depth, value in depth_list:
if depth == 0:
if current_list:
result.append(current_list)
current_list = None
current_list = current_item
current_item.append(value)
level_dict[0] = current_list
elif depth == current_level:
current_item.append(value)
elif depth == current_level + 1:
append_item = []
level_dict[depth] = current_item
current_item.append(append_item)
append_item.append(value)
current_item = append_item
current_level += 1
else:
level_dict[depth].append(value)
if current_list:
result.append(current_list)
print result
这个想法是为了跟踪上一个级别。我还将所有级别安全地保存在字典中,以便在先前检查的级别上插入项目。比如你在6级物品上,你在等7级物品,结果出现了4级物品,你就得相应地更新列表。
更新
我认为这个解决方案比另一个更清晰。它会比较慢,因为它会对输入进行排序,但是如果您没有 10.000 项或更多项这样的输入,它不会产生很大的不同,并且您的代码会变得清晰。此外,这种方法总是将项目放在级别之前。此功能假定您在每个级别至少提供一个项目。因此,鉴于这些事实,这里是解决方案:
from itertools import groupby
depth_list = [[0, 'Hips'], [1, 'Spine'], [2, 'Spine1'], [3, 'Spine2'], [4, 'Neck'], [5, 'Head'], [6, 'HeadTop_End'], [4, 'LeftShoulder'], [5, 'LeftArm'], [6, 'LeftForeArm'], [7, 'LeftHand']]
result = []
current_level = result
get_level_number = lambda item_info: item_info[0]
sorted_by_level = sorted(depth_list, key=get_level_number)
grouped_by_level = groupby(sorted_by_level, key=get_level_number)
for level_number, grouped_items in grouped_by_level:
level = [tag for level, tag in grouped_items]
print level_number, level
current_level.append(level)
current_level = level
print result
您可以递归地执行此操作,如下所示:
depth_list = [[0,'Hips'],[1,'Spine'],[2,'Spine1'],[3,'Spine2'],[4,'Neck'],[5,'Head'],[6,'HeadTop_End'],[4,'LeftShoulder']]
def construct(depth_list, current_level=0):
output = []
while len(depth_list) > 0:
new_level, new_name = depth_list[0]
if new_level == current_level:
output.append([new_name])
depth_list.pop(0)
elif new_level > current_level:
child = construct(depth_list, new_level)
output[-1].extend(child)
else:
return output
return output
print(construct(depth_list))
基本思想是递归遍历输入列表。每次遇到一个元素,你都会做以下三件事之一:
- 如果关节处于同一层级,则从
depth_list
中移除关节并将其添加到输出(包含当前层级的所有关节)。
- 如果关节更深一层,则不要修改
depth_list
而是递归获取子树。然后,将该树添加到输出列表中的最后一个元素,即当前关节。 (递归调用还将从 depth_list
中删除正确数量的元素)。
- 如果它处于较浅的层次,则放弃 return 并让父级继续循环
depth_list
. 的其余部分
请注意,此函数是 破坏性的 -- 一旦函数完成,它将 depth_list
完全留空。如果要保留它,请在调用函数之前复制列表:
copy = list(depth_list)
print(construct(copy))
我打算自动化装配过程,并尝试构建 C4D Python 脚本。我正在尝试将基于深度值的列表镜像到嵌套列表。
假设我们有一个包含深度值的列表:
depth_list = [[0,'Hips'],[1,'Spine'],[2,'Spine1'],[3,'Spine2'],[4,'Neck'],[5,'Head'],[6,'HeadTop_End'],[4,'LeftShoulder']]
我们希望这个成为一个基于深度值的嵌套联合列表:
joint_list = [['Hips',['Spine',['Spine1',['Spine2',['Neck',['Head',['HeadTop_End']]],['LefShoulder']]]]]]
我已经走到这一步了:
for joint in depth_list:
this_depth = joint[0]
try:
joint_list.append(0)
except IndexError:
pass
这是我从 C4D 树导出脚本中得到的原始数据
0 Hips
1 Spine
2 Spine1
3 Spine2
4 Neck
5 Head
6 HeadTop_End
4 LeftShoulder
这是一张图片:
[![enter image description here][1]][1]
祝大家一千万快乐!
你可以试试这个代码:
depth_list = [[0,'Hips'],[1,'Spine'],[2,'Spine1'],[3,'Spine2'],[4,'Neck'],[5,'Head'],[6,'HeadTop_End'],[4,'LeftShoulder']]
result = []
current_list = None
current_item = []
current_level = 0
level_dict = {}
for depth, value in depth_list:
if depth == 0:
if current_list:
result.append(current_list)
current_list = None
current_list = current_item
current_item.append(value)
level_dict[0] = current_list
elif depth == current_level:
current_item.append(value)
elif depth == current_level + 1:
append_item = []
level_dict[depth] = current_item
current_item.append(append_item)
append_item.append(value)
current_item = append_item
current_level += 1
else:
level_dict[depth].append(value)
if current_list:
result.append(current_list)
print result
这个想法是为了跟踪上一个级别。我还将所有级别安全地保存在字典中,以便在先前检查的级别上插入项目。比如你在6级物品上,你在等7级物品,结果出现了4级物品,你就得相应地更新列表。
更新
我认为这个解决方案比另一个更清晰。它会比较慢,因为它会对输入进行排序,但是如果您没有 10.000 项或更多项这样的输入,它不会产生很大的不同,并且您的代码会变得清晰。此外,这种方法总是将项目放在级别之前。此功能假定您在每个级别至少提供一个项目。因此,鉴于这些事实,这里是解决方案:
from itertools import groupby
depth_list = [[0, 'Hips'], [1, 'Spine'], [2, 'Spine1'], [3, 'Spine2'], [4, 'Neck'], [5, 'Head'], [6, 'HeadTop_End'], [4, 'LeftShoulder'], [5, 'LeftArm'], [6, 'LeftForeArm'], [7, 'LeftHand']]
result = []
current_level = result
get_level_number = lambda item_info: item_info[0]
sorted_by_level = sorted(depth_list, key=get_level_number)
grouped_by_level = groupby(sorted_by_level, key=get_level_number)
for level_number, grouped_items in grouped_by_level:
level = [tag for level, tag in grouped_items]
print level_number, level
current_level.append(level)
current_level = level
print result
您可以递归地执行此操作,如下所示:
depth_list = [[0,'Hips'],[1,'Spine'],[2,'Spine1'],[3,'Spine2'],[4,'Neck'],[5,'Head'],[6,'HeadTop_End'],[4,'LeftShoulder']]
def construct(depth_list, current_level=0):
output = []
while len(depth_list) > 0:
new_level, new_name = depth_list[0]
if new_level == current_level:
output.append([new_name])
depth_list.pop(0)
elif new_level > current_level:
child = construct(depth_list, new_level)
output[-1].extend(child)
else:
return output
return output
print(construct(depth_list))
基本思想是递归遍历输入列表。每次遇到一个元素,你都会做以下三件事之一:
- 如果关节处于同一层级,则从
depth_list
中移除关节并将其添加到输出(包含当前层级的所有关节)。 - 如果关节更深一层,则不要修改
depth_list
而是递归获取子树。然后,将该树添加到输出列表中的最后一个元素,即当前关节。 (递归调用还将从depth_list
中删除正确数量的元素)。 - 如果它处于较浅的层次,则放弃 return 并让父级继续循环
depth_list
. 的其余部分
请注意,此函数是 破坏性的 -- 一旦函数完成,它将 depth_list
完全留空。如果要保留它,请在调用函数之前复制列表:
copy = list(depth_list)
print(construct(copy))