Nested 'any' and 'all' condition in Python - python

I have a list of lists
list1 = [['a','b','c'],['m','n','o'],['x','y','z']]
Now, I want to check if all elements of any one of these 'sub-lists' are present in an incoming list called list2.
For example, if
list2 = ['a','c','e','b'] #Code would return True as a,b,c all from list1[0] match
list2 = ['a','c','m','x','e'] # False as all elements from any one sub-list do not match
list2 = ['g','h','i','x','y','z'] # True as all elements from list1[2] matched
I know that this can be done using a nested all within any python function. If list1 was not a nested list, I would have used
result = any(elem in list2 for elem in list1) # To check for any one
or
result = all(elem in list2 for elem in list1) # To check for all
However, I am at loss to do a nested any/all type of list comprehension. Any guidance would be appreciated.

You can do a combination of any and all:
list1 = [['a','b','c'],['m','n','o'],['x','y','z']]
def test(l1, l2):
return any(all(x in l2 for x in sub) for sub in l1)
print(test(list1, ['a','c','e','b']))
print(test(list1, ['a','c','m','x','e']))
print(test(list1, ['g','h','i','x','y','z']))
Output:
True
False
True
The test means: if all x's of any of the sublists are in list2.

Why not make list2 a set and use set.issuperset to see if all elements are in list2
list2 = {'g','h','i','x','y','z'}
print(any(list2.issuperset(elem) for elem in list1))
#True
You can even make this more simple using map although the comprehension is more readable
any(map(list2.issuperset, list1))
If you go this route I suggest not using list2 as the name to avoid confusion

Related

How to check if any element in list 1 is not present in list 2? - python

I have 2 lists:
list1 = [1,2,3,4]
list2 = [1,2,3]
How do I go about checking if there are any elements in list1 that are not in list2?
My current code which for some reason does not work:
if not any(item in list1 for item in list2):
print(True)
I've tried the reverse as well, but it also doesn't work:
if not any(item in list2 for item in list1):
print(True)
So ideally I should get True as an output because the element 4 in list1 doesn't exist in list2, but I don't.
I'd like to know the reasoning behind why my code is incorrect as well. Thanks in advance.
You're taking the negative of the entire check. This will return the correct result
list1 = [1,2,3,4]
list2 = [1,2,3]
if any(item not in list2 for item in list1):
print(True)
The problem is that
any(item in list2 for item in list1)
Will return True if any item in list2 is in list1, which we can agree there is. Another option is using
all(item in list2 for item in list1)
which will return False because not all of the items's in list1 are in list2. If you negate this with not all you will achieve the expected result.

Check if part of a multi-dimensional list is in a seperate muti-dimensional list

Here is some example code.
list1 = [['one','a'],['two','a'],['three','a'],['four','a']]
list2 = [['three','b'],['four','a'],['five','b']]
for l in list1:
if l not in list2:
print(l[0])
and the output from this code.
one
two
three
because ['four','a'] does indeed appear in both lists.
What I am trying to do is check if just the first item of each entry within the first list appears in the second list, I have tried variations of the following
list1 = [['one','a'],['two','a'],['three','a'],['four','a']]
list2 = [['three','b'],['four','a'],['five','b']]
for l in list1:
if l[0] not in list2:
print(l[0])
however, that code returns
one
two
three
four
though both 'three' and 'four' do appear in the second list.
I have used different methods before now to find the values that appear in only one of a pair of lists, then used that to make a master list that contains all possible values with no duplicates and I believe the same should be possible using this method but the syntax is a mystery to me. Where I am going wrong here?
You could use not any() and then you check specific requirements in the comprehension:
list1 = [['one','a'],['two','a'],['three','a'],['four','a']]
list2 = [['three','b'],['four','a'],['five','b']]
for l in list1:
if not any(l[0] == l2[0] for l2 in list2):
print(l[0])
# one
# two
You could also use sets if order doesn't matter:
list1 = [['one','a'],['two','a'],['three','a'],['four','a']]
list2 = [['three','b'],['four','a'],['five','b']]
set(l[0] for l in list1) - set(l2[0] for l2 in list2)
# {'one', 'two'}
you can use set operations
list1 = [['one','a'],['two','a'],['three','a'],['four','a']]
list2 = [['three','b'],['four','a'],['five','b']]
result = set(i[0] for i in list1) - set(i[0] for i in list2)
print(result)
# output {'one', 'two'}

How to compare two lists with different lengths and remove some elements?

I have two lists, the first contains some elements that don't exist in the second list which have more elements. I need to delete elements that don't exist in the second list.
In the example below, I need to delete just the '0' from the first list.
So:
Input:
list1 = [0,1,2,3]
list2 = [1,2,3,4,5,6,7]
Output:
list1 = [1,2,3]
list2 = [1,2,3,4,5,6,7]
I tried this simple code but it return an empty list
list1=[0,1,2,3]
list2=[1,2,3,4,5,6,7]
for element in list1:
for element1 in list2:
if element != element1:
for element in list1:
list1.remove(element)
print(list1)
Any help please ?
You can use sets to do this!
set(list1).intersection(list2) # [1,2,3]
You can also use list comprehension but it's slower in theory.
list1 = [0,1,2,3]
list2 = [1,2,3,4,5,6,7]
list1 = [x for x in list1 if x in list2] # [1,2,3]

Search through lists in Python to find matches?

I have Python lists with various strings in them such as:
List1 = ["a","b","c","d"]
List2 = ["b","d","e","f"]
List3 = []
List4 = ["d","f","g"]
I need to iterate through these lists, provided they are not blank, and finds items that are in all non-blank lists. In the above example, the exact matches list would be ["d"], since that is the only item that appears in all non-blank lists. List3 is blank, so it would not matter that it is not in that list.
Here's some functional programming beauty:
from operator import and_
from functools import reduce
Lists = List1, List2, List3, List4
result = reduce(and_, map(set, filter(None, Lists)))
I can't test this right now, but something like the following should work:
intersection(set(l) for l in [List1, List2, List3, List4] if l)
It uses Python's built-in set datatype to do the intersection operation.
for thing in list1: # iterate each item, you can check before hand if its not empty
if len(list2) > 0: # if not empty
if thing in list2: # in the list
# do the same thing for the other lists
something like that

Test if two lists of lists are equal

Say I have two lists of lists in Python,
l1 = [['a',1], ['b',2], ['c',3]]
l2 = [['b',2], ['c',3], ['a',1]]
What is the most elegant way to test they are equal in the sense that the elements of l1 are simply some permutation of the elements in l2?
Note to do this for ordinary lists see here, however this uses set which does not work for lists of lists.
l1 = [['a',1], ['b',2], ['c',3]]
l2 = [['b',2], ['c',3], ['a',1]]
print sorted(l1) == sorted(l2)
Result:
True
Set doesn't work for list of lists but it works for list of tuples. Sou you can map each sublist to tuple and use set as:
>>> l1 = [['a',1], ['b',2], ['c',3]]
>>> l2 = [['b',2], ['c',3], ['a',1]]
>>> print set(map(tuple,l1)) == set(map(tuple,l2))
True
For one liner solution to the above question, refer to my answer in this question
I am quoting the same answer over here. This will work regardless of whether your input is a simple list or a nested one.
let the two lists be list1 and list2, and your requirement is to
ensure whether two lists have the same elements, then as per me,
following will be the best approach :-
if ((len(list1) == len(list2)) and
(all(i in list2 for i in list1))):
print 'True'
else:
print 'False'
The above piece of code will work per your need i.e. whether all the
elements of list1 are in list2 and vice-verse. Elements in both the lists need not to be in the same order.
But if you want to just check whether all elements of list1 are
present in list2 or not, then you need to use the below code piece
only :-
if all(i in list2 for i in list1):
print 'True'
else:
print 'False'
The difference is, the later will print True, if list2 contains some
extra elements along with all the elements of list1. In simple words,
it will ensure that all the elements of list1 should be present in
list2, regardless of whether list2 has some extra elements or not.

Categories

Resources