当值是不同长度的列表时,使用字典更新列表

时间:2019-12-08 09:47:29

标签: python python-3.x list dictionary variable-length-array

***更新**** 附加字母“ 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"]]

**请仅查看上述输入/输出

3 个答案:

答案 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)

发挥功能性编程的力量。我使用了itertoolscycleislicezip:{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']]

让我知道它是否对您有用。干杯!