【问题标题】:Get unique products between lists and maintain order of input获取列表之间的唯一产品并保持输入顺序
【发布时间】:2018-10-15 01:56:57
【问题描述】:

关于列表的唯一(笛卡尔)乘积有很多问题,但我正在寻找在任何其他问题中都没有找到的特殊问题。

我的输入将始终包含两个列表。当列表相同时,我想获得所有组合,但当它们不同时,我需要独特的产品(即顺序无关紧要)。 然而,此外,我还需要保留顺序,因为 输入 列表的顺序很重要。事实上,我需要的是第一个列表中的项目应该始终是产品元组的第一项。

我有以下工作代码,它可以满足我的要求,但我没有设法找到一种好的、有效的方法来保持如上所述的物品顺序。

import itertools

xs = ['w']
ys = ['a', 'b', 'c']

def get_up(x_in, y_in):
    if x_in == y_in:
        return itertools.combinations(x_in, 2)
    else:
        ups = []
        for x in x_in:
            for y in y_in:
              if x == y:
                  continue
              # sort so that cases such as (a,b) (b,a) get filtered by set later on
              ups.append(sorted((x, y)))
        ups = set(tuple(up) for up in ups)
        return ups

print(list(get_up(xs, ys)))
# [('c', 'w'), ('b', 'w'), ('a', 'w')]

如您所见,结果是按字母顺序排列的唯一元组列表。我使用了排序,所以我可以使用集合过滤重复的条目。但是因为第一个列表 (xs) 包含 w,我希望元组将 w 作为第一项。

[('w', 'c'), ('w', 'b'), ('w', 'a')]

如果两个列表之间存在重叠,则两个列表中出现的项目的顺序无关紧要。因此对于xs = ['w', 'a', 'b']ys = ['a', 'b', 'c']a 的顺序无关紧要

[('w', 'c'), ('w', 'b'), ('w', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'c')]
                                         ^

[('w', 'c'), ('w', 'b'), ('w', 'a'), ('a', 'c'), ('b', 'a'), ('b', 'c')]
                                                     ^

我最好最终得到一个生成器(combinations 返回)。我也只对 Python >= 3.6 感兴趣。

【问题讨论】:

    标签: python unique generator cartesian-product


    【解决方案1】:

    以保持顺序的方式收集元组(当列表相同时),然后通过删除其倒数也在列表中的元组进行过滤。

    if x_in == y_in:
            return itertools.combinations(x_in, 2) 
        else:
            seen = set()
            for a,b in itertools.product(x_in, y_in):
                if a == b or (b, a) in seen:
                    continue
                else:
                    yield (a,b)
                    seen.add((a,b))
    

    这将为您提供(x, y) 顺序的元组;当(a,b)(b,a) 同时出现时,您只会得到最先看到的顺序。

    【讨论】:

      【解决方案2】:

      我会回答我自己的问题,但我敢打赌使用 itertools 或其他工具会有更好的解决方案。

      xs = ['c', 'b']
      ys = ['a', 'b', 'c']
      
      
      def get_unique_combinations(x_in, y_in):
          """ get unique combinations that maintain order, i.e. x is before y """
          yielded = set()
          for x in x_in:
              for y in y_in:
                  if x == y or (x, y) in yielded or (y, x) in yielded:
                      continue
      
                  yield x, y
                  yielded.add((x, y))
      
          return None
      
      print(list(get_unique_combinations(xs, ys)))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-18
        • 2020-10-13
        • 2015-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-28
        • 1970-01-01
        相关资源
        最近更新 更多