【问题标题】:Check if a list is in a custom order检查列表是否按自定义顺序
【发布时间】:2019-09-20 07:50:13
【问题描述】:

我正在尝试验证一个列表说:

X = ['a','c', 'c', 'b', 'd','d','d']

针对自定义排序列表:

Y = ['a',b','d']

在这种情况下,针对 Y 验证的 X 应该返回 True,无论其中有多少额外元素和重复项,只要它符合 Y 中的顺序并包含至少两个元素。

案例示例:

X = ['a','b'] # Returns True
X = ['d','a', 'a', 'c','b'] # Returns False
X = ['c','a','b', 'b', 'c'] # Returns True

我现在能做的最多就是删除重复的元素和多余的元素。我不想使用自定义列表对它们进行排序。我只需要验证订单。我所做或至少尝试过的是创建一个字典,其中值是订单的索引。谁能指出我正确的方向?

【问题讨论】:

    标签: python-3.x list python-3.6


    【解决方案1】:
    from itertools import zip_longest, groupby
    
    okay = list(x == y for y, (x, _) in zip_longest(
            (y for y in Y if y in X), groupby(x for x in X if x in Y)))
    print(len(okay) >= 2 and all(okay))
    

    首先,我们从两个列表中丢弃不必要的元素。然后我们可以使用groupby 折叠X 的相同元素的序列。例如,您的第一个示例 ['a', 'c', 'c', 'b', 'd', 'd', 'd'] 首先变为 ['a', 'c', 'c', 'b'] (by discarding the unnecessary'd'), then[('a', _), ('c', _), ('b', _)]。如果我们逐个元素地将它的键与Y 进行比较,没有不必要的位,并且至少有两个,我们就有一个匹配项。如果违反了顺序(例如['b', 'c', 'c', 'a', 'd', 'd', 'd'],则okay 中会有一个False,它会失败。如果某处出现额外的元素,则会与None 进行比较(感谢@987654332 @),同样False 将在okay 中。

    这可以通过使用集合来提高成员资格查找速度。

    【讨论】:

      【解决方案2】:

      从 X 创建一个新列表,该列表仅包含 Y 中的元素而没有重复项。然后,类似地,从 Y 中删除所有不包含在 X 中的元素并进行重复数据删除。那么你的检查只是一个简单的相等检查。

      def deduplicate(iterable):
          seen = set()
          return [seen.add(x) or x for x in iterable if x not in seen]
      
      def goes_with_order(X, Y):
          Xs = set(X); Ys = set(Y)
          X = deduplicate(x for x in X if x in Ys)
          Y = deduplicate(y for y in Y if y in Xs)
          return X == Y
      

      【讨论】:

      • 这需要澄清您的解释或我的解释是否是 OP 的意图,但您的代码将为 X = [1, 2, 3, 1]Y = [1, 2, 3] 返回 True;我的将返回False。您的也忽略了至少 2 个元素的要求(尽管我也不能 100% 确定我的解释是否正确)。但是,我确信 OP 可以从我们的两个解决方案中粉碎一些东西......
      • @Amadan 长度二的东西我不清楚,只是简单地添加了,所以我把它省略了。
      猜你喜欢
      • 2015-05-14
      • 2021-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多