python中确定两个列表(list)之间是否为子集关系

  1. 将列表(list)转换成集合(set)作比较


>>> A = [1,2,3,4,5]
>>> B = [1,2,3]
>>> C = [1,2,3,4,5]

>>> set(A) < set(B)      #A是B的真子集?False
False
>>> set(A) > set(B)      #B是A的真子集?True
True
>>> set(A) > set(C)      #C是A的真子集?False
False
>>> set(A) >= set(C)     #C是A的子集?True
True

这种方法在某些情况下可能不适用,比如列表中有重复值的情况下:

>>> D = [1,2,3,4,4,4,5,5,5]
>>> print set(D)        #列表转换成集合时会去重,在某些场景下需要考虑这个问题。
set([1, 2, 3, 4, 5])

除此之外,转换成集合的形式,还可以做更多的操作,求交集、并集、差集等等。


  1. 列表(list)通过逻辑操作比较


两个列表 A 和 B,其中 A 与 B 中的一个元素存在,如下:

>>> A = [1,2,3]           
>>> B = [4,5,6,[1,2,3],7]
>>> C = [1,2,3,4,5,6,7]
>>> A in C
False
>>> A in B
True
>>> print B[3]
[1, 2, 3]

A整体作为一个元素,也算是子集。只含有A这个列表的子集。

上面的方式算是个特例。
此外,还有一种方式可以实现:


>>> A = [1,2,3]
>>> B = [1,2,3,4,5,6]
>>> any([A==B[i:i+len(A)] for i in range(0,len(B)-len(A)+1)])
True

我们来分析下这套语句的工作原理:

any([A==B[i:i+len(A)] for i in range(0,len(B)-len(A)+1)])

由外向内分离,整体两层
any()A==B[i:i+len(A)] for i in range(0,len(B)-len(A)+1)

any(),只要其中任何一项为True就返回True。

>>> any([True,False,False])
True
>>> any([False,False,False])
False

A==B[i:i+len(A)] for i in range(0,len(B)-len(A)+1),一个for循环的简单写法。

简单套一下,可以知道循环B比A的列表长度长的次数,每次把B列表的切割和A列表作比较,看是否相等。所以上述步骤是这样的。

>>> A = [1,2,3]      
>>> B = [1,2,3,4,5,6]
>>> [A==B[i:i+len(A)] for i in range(0,len(B)-len(A)+1)]
[True, False, False, False]
>>> any([True, False, False, False])
True

我们理解这条语句是如何工作的之后,我们会发现一个问题就是当A列表和B列表的切片比对时,可能会发生因为顺序不匹配导致无法认定为子集的情况,这显然是不符合数学上的定义的。

>>> A = [1,2,3]      
>>> B = [1,4,3,2,5,6]
>>> any([A==B[i:i+len(A)] for i in range(0,len(B)-len(A)+1)])
False

可以看到只是把B列表的顺序改动了下,得到的是截然不同的结果。
所以在选择方法时,需要根据实际情况来决定那种方式适合你的程序或脚本。

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值