【问题标题】:Writing function that checks if lists have the same elements编写检查列表是否具有相同元素的函数
【发布时间】:2016-01-30 23:50:56
【问题描述】:

编辑:这是一个明确地关于列表和函数的学习练习。因此不允许将列表转换为集合。

我需要编写一个函数def sameSet(a,b) 来检查两个列表是否按某种顺序具有相同的元素,忽略重复项。例如,两个列表 [1, 4, 9, 16, 9, 7, 4, 9, 11] 和 [11, 11, 7, 9, 16, 4, 1] 将被视为相等。

这就是我所做的。我首先定义了一个辅助函数def contained(list1, list2),它检查列表1 是否包含在列表2 中,只要列表1 的元素在列表2 中,就增加一个计数器。最后,如果计数器等于列表1 的长度,我将布尔变量 same 设置为 True,因为这意味着列表 1 中的每个元素也在列表 2 中。

    def main():
        list1 = [1, 4, 9, 16, 9, 7, 4, 9, 11, 11]
        list2 = [11, 11, 7, 9, 16, 4, 1]

    def sameSet(list1, list2):
        contained(list1, list2)
        contained(list2, list1)


    def contained(list1, list2):

        same = False
        count = 0

        for element in list1:
            if element in list2:
                count = count + 1
            else:
                count = count

        if count == len(list1):
            same = True

        return same

    main()

我不确定要为函数sameSet 写什么。我希望它检查布尔变量same 是否设置为True 用于两个包含(即如果list1 在list2 中,如果list2 在list1 中,意味着它们是相等的)。但我不知道如何在 Python 中实现这一点,以便程序正常工作。任何帮助将不胜感激。

【问题讨论】:

    标签: python


    【解决方案1】:

    将两个列表转换为集合,然后比较集合

    >>> list1 = [1, 4, 9, 16, 9, 7, 4, 9, 11] 
    >>> list2 =  [11, 11, 7, 9, 16, 4, 1]
    >>> set(list1) == set(list2)
    True
    

    【讨论】:

    • 感谢您的提示,但问题在于明确的列表(这实际上是重点)。我正在研究这本书,还没有提到套​​装。
    • @Kamil:你可能想用这个事实更新你的问题,这是一个不使用集合来处理列表的学习练习。
    【解决方案2】:

    我重构了您的代码以使其更具 Python 风格,并运行了几个测试...以及一些打印输出以便快速检查。

    您包含的函数也适用于下面的 SameSet 函数,但效率不高。它有不必要的变量等等......

    def sameSet(list1, list2):
            if contained(list1, list2) and contained(list2, list1):
                    print("the same!!")    
            else:
                print("not the same")
    
    
    def contained(list1, list2):
    
        for element in list1:
            if element not in list2:
               return False
    
        return True
    
    def main():
        # this prints "the same"
        sameSet([1, 4, 9, 16, 9, 7, 4, 9, 11, 11], [11, 11, 7, 9, 16, 4, 1])
        # this prints "not the same"
        sameSet([1, 4, 9, 16, 9, 7, 4, 9, 11, 11], [11, 11, 7, 9, 16, 4,12345])
    
    
    if __name__=="__main__":
        main()
    

    【讨论】:

    • 那么我应该在主标题下写什么?
    • 我做了一个重构来保留 main() 函数,在 python 脚本中不一定要有 main()。
    【解决方案3】:

    无需更改代码中的任何内容,我只需放入 sameset 函数:

    if contained(list1,list2)==True and contained(list2,list1)==True:
          return True
    else:
          return False
    

    【讨论】:

    • 其实if contained(list1,list2) and contained(list2,list1): 就足够了,因为它们是布尔值
    【解决方案4】:

    考虑到新的编辑

    要在不使用set 的情况下检查列表l1 是否等于(从相似内容方面)列表l2,您可以使用方便的内置all() 函数。

    您需要确保检查较大列表的值是否all在较小的列表中,否则您将不会没有真正得到你想要的。

    作为一个小示范:

    l1 = [1, 2, 3, 4]
    l2 = [1, 1, 2, 3, 4, 3, 2]
    
    print(all(i in l1 for i in l2))  # True
    
    l2.append(5)  # l2 = [1, 1, 2, 3, 4, 3, 2, 5]
    print(all(i in l1 for i in l2))  # False
    

    但是如果你在执行l2.append(5)之后错误地检查较小的列表l1的内容是否在较大的列表l2中,你会失望的:

    print(all(i in l2 for i in l1)) # Prints True :^)
    

    要将它变成一个函数——并从根本上重新发明all() 轮子——而不做任何“花哨”的事情,你可以做这样的事情:

    def sameSet(a, b):
        # l1 is the large list, l2 the small list
        l1, l2 = (a, b) if len(a) > len(b) else (b, a)
        for val in l1:
            if val not in l2:
                return False
        return True 
    

    哪个做同样的事情。

    【讨论】:

      【解决方案5】:

      使用 dict 和 zip

      def unq(l):
          return sorted(x for x in dict(zip(l,l)))
      
      stat = unq(l1) == unq(l2)
      

      所以构建每个列表的字典并对键列表进行排序,然后只比较 2 个结果,其中 stat 是布尔值(真或假)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-20
        • 2019-05-16
        • 1970-01-01
        • 2021-12-08
        • 1970-01-01
        • 2011-09-01
        • 2012-08-22
        • 2013-11-21
        相关资源
        最近更新 更多