***更新**** 附加字母“ A”是一个问题。我在这里改写。也许更清楚? 我必须使用具有可变长度列表作为其值的字典来替换列表中的值。例如:
variants = {C:["cat", "can", "car"], D:["do","die"], Z:["zen", "zoo"]}
还有一个列表:
Letters = ["C", "D", "Z"]
我想要这样的列表输出
PotentialWords = [["cat", "do", "zen"], ["can", "die", "zoo"],["car", "do", "zen"], ["car", "die", "zoo"]
在每个步骤中所有元素都进行更新,但是如果索引超过,则将保留更新,我们将使所有变体相互交叉。 / p>
到目前为止,我有:
max_len = max([len(words) for words in variants.values()])
for i in range(max_len):
var = []
for let in Letters:
if let not in variants.keys():
var.append(let)
else:
if i < len(variants[let]):
var.append(variants[let][i])
elif i > len(variants[let]):
var.append(let)
哪个给出错误的输出:
OutputWords = [["cat", "do", "zen"], ["can", "die", "zoo"], ["car"]]
您的所有帮助将不胜感激:) *更新* 感谢评论者,此问题已更新为更清晰。之前的输入是
Letters = ["C", "D", "Z", "A"]
并输出
[["cat", "do", "zen", "A"], ["can", "die", "zoo","A"],["car", "A"]]
**请仅查看上述输入/输出
答案 0 :(得分:0)
0 1 2 3
a0 a1 a2
b0 b1 b2 b3
c0 c1
假设您有这些列表,并且字母是[a,b,c],我想您要尝试的是将所有内容填充到最长的长度,然后压缩所有内容。>
它会变成这样,然后您可以阅读各列
0 1 2 3
a0 a1 a2 a0
b0 b1 b2 b3
c0 c1 c0 c1
如果这就是您想要做的,这能解决吗?
max_len = max([len(words) for words in variants.values()])
results = []
for i in range(max_len):
var = []
for let in Letters:
index = i % len(Letters[let])
var.append(Letters[let][index])
results.append(var)
答案 1 :(得分:0)
发挥功能性编程的力量。我使用了itertools
:cycle
,islice
和zip
:{p>
from itertools import cycle, islice
variants = {"C":["cat", "can", "car"], "D":["do","die"], "Z":["zen", "zoo"]}
letters = ["C", "D", "Z"]
def take_first_n_items(iterable, n):
return list(islice(iterable, max_len))
max_len = max([len(words) for words in variants.values()])
phrase_iterables = [cycle(variants[letter]) for letter in letters]
full_values_of_variants = [take_first_n_items(iterable, max_len) for iterable in phrase_iterables]
results = list(zip(*full_values_of_variants))
print(results)
它是如何工作的:
#phrase_iterables = [('cat', 'can', 'car','cat',...), ('do', 'die', 'do', ...) , ('zen', 'zoo', 'zen', 'zoo',...)]
#full_values_of_variants = [['cat', 'can', 'car'], ['do', 'die', 'do'], ['zen', 'zoo', 'zen']]
输出:[('cat', 'do', 'zen'), ('can', 'die', 'zoo'), ('car', 'do', 'zen')]
注意:list(islice(iterable, max_len))
使用不必要的额外迭代。您可以改用islice(iterable, max_len)
。
答案 2 :(得分:0)
我将通过图形来解决这个问题。想象每个列表在图中处于特定深度。
root
/ | \
cat can car
|\ /|\ /|
do die
|\ /|
zen zoo
在这里,我们假设根元素“ root”和列表Letters
是每个列表在图中出现的顺序。因此,C : [cat, can, car]
的深度为1,D: [do, die]
的深度为2 ..依此类推。
我们可以使用以下函数轻松创建此无向图:
variants = {"C":["cat", "can", "car"], "D":["do","die"], "Z":["zen", "zoo"]}
Letters = ["C", "D", "Z"]
def create_graph(list_dict, depth_order):
graph = {"root": set(list_dict[depth_order[0]])}
for i in range(1, len(depth_order)):
parents = list_dict[depth_order[i-1]]
children = list_dict[depth_order[i]]
# Connect parent to children
for elem in parents:
graph[elem] = set(children)
# Connect children tp parent
for elem in children:
graph[elem] = set(parents)
return graph
graph = create_graph(variants, Letters)
print(graph)
请注意,每个级别均已完全连接到下一个级别。因此,如果找到从级别1中的一个元素到最后一级中的另一个元素的路径,我们将找到组合的所有变体。我们可以使用深度优先搜索(link)
def dfs_paths(graph, start, goal):
stack = [(start, [start])]
while stack:
(vertex, path) = stack.pop()
for next in graph[vertex] - set(path):
if next == goal:
yield path + [next]
else:
stack.append((next, path + [next]))
现在,我们可以使用所需的起始节点和结束节点来调用此函数:
print(list(dfs_paths(graph, 'cat', 'zen')))
这将产生:
[['cat', 'die', 'zen'], ['cat', 'die', 'zoo', 'do', 'zen'], ['cat', 'do', 'zen'], ['cat', 'do', 'zoo', 'die', 'zen']]
我们可以过滤此列表以使其仅包含length = len(Letters)
的元素,这将消除DFS跟踪上一级的间接路径。
输出:
[['cat', 'die', 'zen'], ['cat', 'do', 'zen']]
让我知道它是否对您有用。干杯!