Using 'in' to test for part of one sublist in another in Python

旧城冷巷雨未停 提交于 2019-12-12 00:46:01

问题


Newbie here trying to search for part of one sublist within another sublist.

list_1 = [[1, 2, 9], [4, 5, 8]]
list_2 = [[1, 2, 3], [4, 5, 6], [1, 2, 5]]

for item in list_1:
    for otherItem in list_2:
        item[0:2] in otherItem[0:2]

I was hoping this would return

True
False
True
False
True
False

But instead I get false for every iteration. In a nutshell:

list_1[0][0:2] == list_2[0][0:2] #this returns true
list_1[0][0:2] in list_2[0][0:2] #this returns false

I guess I don't understand how in works. Can anyone school me here?


回答1:


in looks to see if one sublist is an element (not sublist) of another list:

[1,2] in [[1,2],[3,4]]

would be True.

[1,2] in [1,2,3]

would be False as would:

[1,2] in [1,2]

However:

[1,2] == [1,2]

would be True. Depending on what you're actually trying to do, set objects might be useful.

a = [1,2]
b = [1,2,3]
c = [3,2,1]
d = [1,1,1]
e = set(a)
len(e.intersection(b)) == len(a)  #True
len(e.intersection(c)) == len(a)  #True -- Order of elements does not matter
len(e.intersection(d)) == len(a)  #False



回答2:


Given your example lists:

list_1 = [[1, 2, 9], [4, 5, 8]]
list_2 = [[1, 2, 3], [4, 5, 6], [1, 2, 5]]

This works:

print [this[0:2]==that[0:2] for this in list_1 for that in list_2]
[True, False, True, False, True, False]

Or, use a set:

print [this for this in list_1 for that in list_2 if set(this[0:2])<set(that)]
[[1, 2, 9], [1, 2, 9], [4, 5, 8]]

Be aware that a set is without order, so:

>>> set([1,2])==set([2,1])
True

A typical use of in is with a string:

>>> 'ab' in 'cbcbab'
True

Or a single element in a sequence:

>>> 100 in range(1000)
True

Or an atomic element in a sequence:

>>> (3,3,3) in zip(*[range(10)]*3)
True

But over lapping list element do not work:

>>> [1,2] in [0,1,2,3]
False

Unless the elements are the same atomic size:

>>> [1,2] in [0,[1,2],3]
True

But you CAN use a string to compare list a being 'in' list b like so:

>>> def stringy(li): return ''.join(map(str,li))
...
>>> stringy([1,2,9][0:2])
'12'
>>> stringy([1,2,9][0:2]) in stringy([1,2,5])
True

So your original intent MAY be to check to see of item[0:2] appears anywhere in otherItem but in the order of 'item' in your loop. You can use a string like so:

>>> print [this for this in list_1 for that in list_2 if stringy(this[0:2]) in stringy(that)]
[[1, 2, 9], [1, 2, 9], [4, 5, 8]]

This is different than the set version since '12'!='21' and '12' not in '21' So if you changed the order of the elements of list_2:

list_1 = [[1, 2, 9], [4, 5, 8]]
list_2 = [[1, 2, 3], [4, 5, 6], [1, 5, 2]]

print [this for this in list_1 for that in list_2 if set(this[0:2])<set(that)]
[[1, 2, 9], [1, 2, 9], [4, 5, 8]]   # same answer since sets are unordered
print [this for this in list_1 for that in list_2 if stringy(this[0:2]) in stringy(that)]
[[1, 2, 9], [4, 5, 8]]              # different answer...



回答3:


print set([1,2]).intersection([1,2,3])==set([1,2])

would be True

using set intersection I think you can get what you want

It is important to note that sets are un-ordered collections unique elements

thus set([1,1,2]) == set([1,2]) and so this may not necessarily work for you for all instances



来源:https://stackoverflow.com/questions/15144009/using-in-to-test-for-part-of-one-sublist-in-another-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!