提问人:iceman 提问时间:5/10/2023 更新时间:5/11/2023 访问量:45
在列表中循环显示潜在结果时遇到问题
Having trouble looping over potential outcomes in a list
问:
我有以下代码,可以遍历现有列表中的每个子列表。因此,它添加每个元素的最后一个元素,并将其从 A-B 映射到每个子列表上。
existing_list = [[1, 2, 3, 4], [2, 3, 4]]
A = [4,5, 6]
B = [5,6, 7]
for i in range(len(existing_list)):
sublist = existing_list[i]
for j in range(len(A)):
if sublist[-1] == A[j]:
sublist.append(B[j])
print(existing_list)
[[1, 2, 3, 4, 5, 6, 7], [2, 3, 4, 5, 6, 7]]
假设我现在想向 A、B 添加重复的元素,但我想为每个元素创建一个唯一的路径。我很难理解从这里去哪里。
如果我将以下元素更改为 A/B,我想要的输出是。
existing_list = [[1, 2, 3, 4], [2, 3, 4]]
A = [4,4,5, 6]
B = [5,6,6, 7]
[[1, 2, 3, 4, 5, 6, 7],[1, 2, 3, 4, 6, 7], [2, 3, 4,5, 6, 7],[2, 3, 4, 6, 7]]
需要帮助循环并制作新列表。对不起,这是我的第一篇文章,如果太密集,我深表歉意。如果您有任何问题,请告诉我。
答:
0赞
oli26
5/10/2023
#1
你可以像这样使用递归函数:
existing_list = [[1, 2, 3, 4], [2, 3, 4]]
A = [4,4,5, 6]
B = [5,6,6, 7]
def map_multiple(sublist):
subsets = []
anyMatches = False
for (key, value) in zip(A, B):
if key == sublist[-1]:
new_sets = map_multiple(sublist + [value])
subsets.extend(new_sets)
anyMatches = True
if not anyMatches:
return [sublist]
return subsets
new_list = []
for i in range(len(existing_list)):
sublist = existing_list[i]
allSubsets = map_multiple(sublist)
new_list.extend(allSubsets)
print(new_list)
评论
1赞
oli26
5/10/2023
只要确保没有 n -> n,否则你的程序将进入无限循环。
0赞
SimonUnderwood
5/10/2023
#2
由于 和 是路径的映射,我将它们解析到字典中。然后,我使用递归函数遍历所有可能的路径,无论分支出现在哪里。A
B
existing_list = [[1, 2, 3, 4], [2, 3, 4]]
A = [4,4,5, 6]
B = [5,6,6, 7]
pathways = {}
for a, b in zip(A, B):
if a not in pathways:
pathways[a] = [b]
else:
pathways[a].append(b)
# creates a dict like this:
# paths = {
# 4: [5, 6],
# 5: [6],
# 6: [7]
# }
def get_paths(starting_path_list: list, pathways: dict) -> list[list]:
all_path_lists = []
while (end_num := starting_path_list[-1]) in pathways:
if len(pathways[end_num]) == 1: # no branching
starting_path_list += pathways[end_num]
else:
for path in pathways[end_num]: # branching
all_path_lists += get_paths(starting_path_list + [path], pathways) # recursive call
break
else: # triggers if while loop ends without break
all_path_lists.append(starting_path_list)
return all_path_lists
new_list = []
for sublist in existing_list:
new_list += get_paths(sublist, pathways)
print(new_list)
# prints: [[1, 2, 3, 4, 5, 6, 7],[1, 2, 3, 4, 6, 7], [2, 3, 4,5, 6, 7],[2, 3, 4, 6, 7]]
与所有递归一样,您需要注意不要创建无限循环。在这里,您需要确保路径中没有任何圆形结构。
0赞
Alain T.
5/11/2023
#3
如果要在非常大的列表上执行此操作,则可能需要使用字典来利用对子列表的直接访问。
例如:
- 构建一个包含子列表的字典,其键与每个子列表中的最后一个数字相对应。请注意,可能有多个以相同值结尾的子列表。因此,该字典中的值将是子列表(以相同的值结尾)
- 此 () 字典将允许您在添加 a->b 链接后通过将子列表从一个结束键移动到另一个结束键来扩展子列表。
ends
- 它还允许您在链接到多个 s 时将多个副本添加到同一个结束键
a
b
- 为了简化 A->B 链接的处理,您可以形成一个字典,其中每个不同的链接作为键,并将相应的 s 列表作为值 (
a
b
ABPaths
) - 使用这两个字典,扩展过程将简单地将所有以值结尾的列表移动到所有结束键(S),以获得任意数量的值(这将隐式创建重复路径)
a
b
b
- 最后,字典中的值将是所有路径
ends
...
existing_list = [[1, 2, 3, 4], [2, 3, 4]]
A = [4,4,5,6]
B = [5,6,6,7]
ends = dict()
for sublist in existing_list:
ends.setdefault(sublist[-1],[]).append(sublist)
print(ends) # {4: [[1, 2, 3, 4], [2, 3, 4]]}
ABPaths = dict()
for a,b in zip(A,B):
ABPaths.setdefault(a,[]).append(b)
print(ABPaths) # {4: [5, 6], 5: [6], 6: [7]}
for a,bs in ABPaths.items():
aEnds = ends.pop(a)
for b in bs:
ends.setdefault(b,[]).extend( e+[b] for e in aEnds )
existing_list = [p for paths in ends.values() for p in paths]
print(existing_list)
# [[1, 2, 3, 4, 6, 7], [2, 3, 4, 6, 7], [1, 2, 3, 4, 5, 6, 7],
[2, 3, 4, 5, 6, 7]]
请注意,这假设 A->B 链接仅指向更大的数字(即 B 中的每个值都大于 A 中的相应值),这在您的示例中是正确的,但在您的实际数据中可能不是这样
评论