结合没有Itertools的两个列表

时间:2018-04-16 17:24:50

标签: python python-3.x

对于项目的一部分,我必须为字典中定义的给定图形显示三种颜色的所有可能组合。这不会检查有效的着色,因为它只是一种辅助方法。

示例

three_color({"A":["B"], "B":["A"]})

 Should give us:

 [{'A': '1', 'B': '1'},
 {'A': '1', 'B': '2'},
 {'A': '1', 'B': '3'},
 {'A': '2', 'B': '1'},
 {'A': '2', 'B': '2'},
 {'A': '2', 'B': '3'},
 {'A': '3', 'B': '1'},
 {'A': '3', 'B': '2'},
 {'A': '3', 'B': '3'}]

但是,我们禁止进口任何图书馆。目前,我正在使用此解决方案并尝试在不使用product()

的情况下进行传输
coloring = ([dict(zip(graph, p)) for p in product(colors,repeat = len(graph))])

我目前的解决方案基于以下事实:根据文档,product(A, B)返回与((x,y) for x in A for y in B).相同的

目前,我有

def three_color(graph):
    colors = ['1','2','3']

    coloring = ([dict(zip(graph, p)) for p in ((x,y) for x in colors for y in (range(1,4)))])
    #coloring = ([dict(zip(graph, p)) for p in product(colors,repeat = len(graph))])

    return coloring

这在使用图{"A":["B"], "B":["A"]}时给出了正确的答案,但是当使用任何其他数量的顶点时它似乎不起作用。

示例2

three_color({"A":["B","C"], "B":["A"], "C":["A"]})

Should give us:
[{'A': '1', 'B': '1', 'C': '1'},
 {'A': '1', 'B': '1', 'C': '2'},
 {'A': '1', 'B': '1', 'C': '3'},
 {'A': '1', 'B': '2', 'C': '1'},
 {'A': '1', 'B': '2', 'C': '2'},
 {'A': '1', 'B': '2', 'C': '3'},
 {'A': '1', 'B': '3', 'C': '1'},
 {'A': '1', 'B': '3', 'C': '2'},
 {'A': '1', 'B': '3', 'C': '3'},
 {'A': '2', 'B': '1', 'C': '1'},
 {'A': '2', 'B': '1', 'C': '2'},
 {'A': '2', 'B': '1', 'C': '3'},
 {'A': '2', 'B': '2', 'C': '1'},
 {'A': '2', 'B': '2', 'C': '2'},
 {'A': '2', 'B': '2', 'C': '3'},
 {'A': '2', 'B': '3', 'C': '1'},
 {'A': '2', 'B': '3', 'C': '2'},
 {'A': '2', 'B': '3', 'C': '3'},
 {'A': '3', 'B': '1', 'C': '1'},
 {'A': '3', 'B': '1', 'C': '2'},
 {'A': '3', 'B': '1', 'C': '3'},
 {'A': '3', 'B': '2', 'C': '1'},
 {'A': '3', 'B': '2', 'C': '2'},
 {'A': '3', 'B': '2', 'C': '3'},
 {'A': '3', 'B': '3', 'C': '1'},
 {'A': '3', 'B': '3', 'C': '2'},
 {'A': '3', 'B': '3', 'C': '3'}]

But it gives me:
[{'A': '1', 'B': 1},
 {'A': '1', 'B': 2},
 {'A': '1', 'B': 3},
 {'A': '2', 'B': 1},
 {'A': '2', 'B': 2},
 {'A': '2', 'B': 3},
 {'A': '3', 'B': 1},
 {'A': '3', 'B': 2},
 {'A': '3', 'B': 3}]

非常感谢任何指导或协助。

2 个答案:

答案 0 :(得分:2)

如果您查看itertools documentation,它们会提供大多数内置函数的实现。

对于product,它们提供的唯一区别是itertools实现不会在内存中建立中间结果。

您可以使用文档中提供的功能,并将其用作示例中的产品功能:

def product(*args, repeat=1):
    pools = [tuple(pool) for pool in args] * repeat
    result = [[]]
    for pool in pools:
        result = [x+[y] for x in result for y in pool]
    for prod in result:
        yield tuple(prod)

def coloring(graph):
  colors = ['1','2','3']
  return [dict(zip(graph, p)) for p in product(colors,repeat = len(graph))]

print(coloring({"A":["B","C"], "B":["A"], "C":["A"]}))

输出:

[{'A': '1', 'B': '1', 'C': '1'}, {'A': '1', 'B': '1', 'C': '2'}, {'A': '1', 'B': '1', 'C': '3'}, {'A': '1', 'B': '2', 'C': '1'}, {'A': '1', 'B': '2', 'C': '2'}, {'A': '1', 'B': '2', 'C': '3'}, {'A': '1', 'B': '3', 'C': '1'}, {'A': '1', 'B': '3', 'C': '2'}, {'A': '1', 'B': '3', 'C': '3'}, {'A': '2', 'B': '1', 'C': '1'}, {'A': '2', 'B': '1', 'C': '2'}, {'A': '2', 'B': '1', 'C': '3'}, {'A': '2', 'B': '2', 'C': '1'}, {'A': '2', 'B': '2', 'C': '2'}, {'A': '2', 'B': '2', 'C': '3'}, {'A': '2', 'B': '3', 'C': '1'}, {'A': '2', 'B': '3', 'C': '2'}, {'A': '2', 'B': '3', 'C': '3'}, {'A': '3', 'B': '1', 'C': '1'}, {'A': '3', 'B': '1', 'C': '2'}, {'A': '3', 'B': '1', 'C': '3'}, {'A': '3', 'B': '2', 'C': '1'}, {'A': '3', 'B': '2', 'C': '2'}, {'A': '3', 'B': '2', 'C': '3'}, {'A': '3', 'B': '3', 'C': '1'}, {'A': '3', 'B': '3', 'C': '2'}, {'A': '3', 'B': '3', 'C': '3'}]

答案 1 :(得分:0)

您可以使用简单的递归和生成器函数,然后使用zip将完整的颜色与图形配对:

def full_product(d, d1, current = []):
   if d == len(current):
      yield current
   else:
      for i in range(d):
        for b in range(1, d1):
           yield from full_product(d, d1, current + [b])

def final_results(data):
  def wrapper():
    for colors in data():
       full_set = set(reduce(lambda x, y:x+y, [[a]+b for a, b in colors.items()]))
       result = list(full_product(len(full_set), 4))
       last_result = [a for i, a in enumerate(result) if all(a != c for c in result[:i])]
       yield [dict(zip(full_set, i)) for i in last_result]
  return wrapper

@final_results
def full_results():
   return [{"A":["B"], "B":["A"]}, {"A":["B","C"], "B":["A"], "C":["A"]}]

print(list(full_results()))

输出:

[[{'A': 1, 'B': 1}, {'A': 1, 'B': 2}, {'A': 1, 'B': 3}, {'A': 2, 'B': 1}, {'A': 2, 'B': 2}, {'A': 2, 'B': 3}, {'A': 3, 'B': 1}, {'A': 3, 'B': 2}, {'A': 3, 'B': 3}], [{'A': 1, 'B': 1, 'C': 1}, {'A': 1, 'B': 1, 'C': 2}, {'A': 1, 'B': 1, 'C': 3}, {'A': 1, 'B': 2, 'C': 1}, {'A': 1, 'B': 2, 'C': 2}, {'A': 1, 'B': 2, 'C': 3}, {'A': 1, 'B': 3, 'C': 1}, {'A': 1, 'B': 3, 'C': 2}, {'A': 1, 'B': 3, 'C': 3}, {'A': 2, 'B': 1, 'C': 1}, {'A': 2, 'B': 1, 'C': 2}, {'A': 2, 'B': 1, 'C': 3}, {'A': 2, 'B': 2, 'C': 1}, {'A': 2, 'B': 2, 'C': 2}, {'A': 2, 'B': 2, 'C': 3}, {'A': 2, 'B': 3, 'C': 1}, {'A': 2, 'B': 3, 'C': 2}, {'A': 2, 'B': 3, 'C': 3}, {'A': 3, 'B': 1, 'C': 1}, {'A': 3, 'B': 1, 'C': 2}, {'A': 3, 'B': 1, 'C': 3}, {'A': 3, 'B': 2, 'C': 1}, {'A': 3, 'B': 2, 'C': 2}, {'A': 3, 'B': 2, 'C': 3}, {'A': 3, 'B': 3, 'C': 1}, {'A': 3, 'B': 3, 'C': 2}, {'A': 3, 'B': 3, 'C': 3}]]