【问题标题】:Cartesian product with specific order具有特定顺序的笛卡尔积
【发布时间】:2021-11-20 21:22:25
【问题描述】:

我需要按特定顺序输出 N 个列表的笛卡尔积。

我知道如何以“默认”顺序构建产品:

给定集合(a, b, c), (x, y), (1, 2, 3),首先我产生ax1,然后遍历最后一组得到ax2ax3,然后更改第二组中的元素并再次遍历最后一组得到ay1ay2ay3等……

在生产 N-1 元素的产品之前,我需要的顺序不应该是任何集合中的 N-th 元素

想要的结果是ax1, ax2, ay1, ay2, bx1, bx2, by1, by2, ax3, ay3, bx3, by3, cx1, cx2, cx3, cy1, cy2, cy3。看,在生产具有第二个元素的所有产品之前,我没有得到ax3(包含来自(1, 2, 3) 的第三个元素)。

我目前的算法是:

  • 截断设置为长度1
  • 生成产品
  • 将集合截断为长度2
  • 生成产品
  • 删除重复项,保留顺序
  • ...
  • 将集合截断为长度max length of all sets
  • 生成产品
  • 删除重复项,保留顺序

每一步“生成产品”也会生成上一步的所有产品,所以我必须将它们删除

获得所需订单的算法是否更好?有名字吗?

【问题讨论】:

    标签: algorithm combinatorics cartesian-product


    【解决方案1】:

    不确定此订单是否有名称,但这似乎可以满足您的要求,而无需删除重复的项目。

    from itertools import islice, product, zip_longest
    
    def specific_order_cartesian(lists):
        its = [[lst[0]] for lst in lists]
        yield tuple(lst[0] for lst in lists)
    
        for column in list(islice(zip_longest(*lists), 1, None)):
            for i, p in reversed(list(enumerate(column))):
                if p is None:
                    continue
    
                yield from product(
                    *(
                        (p,) if j == i else its[j]
                        for j in range(len(lists))
                    )
                )
    
                its[i].append(p)
    
    
    print(list(specific_order_cartesian(
        [('a', 'b', 'c',), ('x', 'y'), (1, 2, 3)]
    )))
    

    【讨论】:

      猜你喜欢
      • 2017-03-31
      • 2021-05-06
      • 1970-01-01
      • 2020-07-23
      • 1970-01-01
      • 2020-07-26
      • 2018-08-31
      • 2020-09-15
      • 1970-01-01
      相关资源
      最近更新 更多