Checking if two lists share at least one element [duplicate] - python

This question already has answers here:
Test if lists share any items in python
(9 answers)
Closed 4 years ago.
I have two lists, for example:
a = ["mail1", "mail2", "mail3", "mail4"]
b = ["mail2", "mail5"]
and I want to check if any of the elements in list b also appears in list a.
I wanted to know if there is a way (and what is it) to do this without a for loop.
Also I wanted to know how can I create a list of boolean values, where each value will be the result of the comparison of values a[i] and b[i], something like:
[z for i, j in zip(a, b) z = i == j] # (just with the right syntax)
z will be 1 if in some place i == j, so I can check the array for any 'True' values.

You can use any:
any(x in a for x in b)
The nice thing about this generator expression is that any will return True as soon as the generator yields a True, i.e. there won't be redundant x in a lookups.
Edit:
You can improve the time complexity by making a set from a.
a_set = set(a)
any(x in a_set for x in b)
Regarding your new question:
[x == y for x,y in zip(a,b)]

Elegant way is to use sets:
a = ["mail1", "mail2", "mail3", "mail4"]
b = ["mail2", "mail5"]
anb = set(a) & set(b)
print anb
if anb:
print True
>>> set(['mail2'])
>>> True

The any function takes in an iterable (See documentation here), so the answer should be any([x in a for x in b])

Related

List comprehension syntax - how to use ... if... else? [duplicate]

This question already has answers here:
if/else in a list comprehension
(12 answers)
Is it possible to use 'else' in a list comprehension? [duplicate]
(6 answers)
Closed 3 years ago.
I'm just getting started with Python and was reading about list comprehensions.
The following code:
my_list = [x ** x for x in range(1,11) if x % 2 == 0]
print(my_list)
... produces this output:
[4, 256, 46656, 16777216, 10000000000]
I then tried this code:
my_list = [x ** x for x in range(1,11) if x % 2 == 0 else 7]
print(my_list)
... but I got a syntax error starting at the second "e" in else.
Can someone explain why I'm getting a syntax error? I'd like to have the list create a list of even squares based on the value of the base (x), and to have the value "49" if the list value is not an "even number" square.
In this case, you would want
my_list = [x ** x if x % 2 == 0 else 49 for x in range(1,11)]
If you use an if at the end of a list comprehension like that, it is used to select which elements to include. If you want a different result depending on the case, you need to use a ternary if at the beginning instead.
For more info, take a look at the docs here. To quote:
A list comprehension consists of brackets containing an expression followed by a for clause, then zero or more for or if clauses. The result will be a new list resulting from evaluating the expression in the context of the for and if clauses which follow it.
There is no support for else here, presumably because a ternary if (if condition then foo else bar) in the 'body' of the comprehension already accomplishes this and "There should be one-- and preferably only one --obvious way to do it."

Ordered subset in python [duplicate]

This question already has answers here:
How to test if one string is a subsequence of another?
(4 answers)
Python list filtering: remove subsets from list of lists
(10 answers)
Closed 4 years ago.
I know many similar questions has been asked before with answers but my concern is related to builtin functionality rather than my own logic of loops and indexes etc.
In my python app, I need to check if listA is subset of listB. I've done this with the help of sets like this
set(listA) < set(listB)
It works fine overall but I also need to check order of objects in list. e.g.
x = ['a','b','c','d']
xx = ['a', 'c']
xxx = ['c' , 'a']
so according to sets definition;
set(xx) < set(x) returns true and set(xxx) < set(x) also returns true...
But I need something that returns false for 2nd case.
Is there any builtin functionality in python or I need to implement my own logic to get required result?
I think a better word for this operation is a subsequence.
You need to write this yourself, but you can do it fairly easily by walking both lists together:
def is_subsequence(a, b):
b_it = iter(b)
try:
for a_val in a:
while next(b_it) != a_val:
pass
except StopIteration:
return False
else:
return True
used as:
>>> is_subsequence(xx, x)
True
>>> is_subsequence(xxx, x)
False
Edit: Searching for "subsequence" finds this great answer.

Python: Using an OR operator for variable number of inequality conditions [duplicate]

This question already has answers here:
Pythonic way of checking if a condition holds for any element of a list
(3 answers)
Closed 4 months ago.
Suppose I have n values in a list x = [1.2, -0.4, 3.5, ....]
I need to check if at least one of them is below zero.
So basically, if I had only two values, I'd have written
if x[0]< 0 or x[1] < 0
But now, I need to use the same or operator within a loop so as to check each one of the values in the list.
The command any(x) < 0 seems to return False every single time.
How would I have to go about it?
any is not vectorized. You'd have to apply it on each object in x:
any(n < 0 for n in x)
n < 0 for n in x creates a generator that yields one value at a time from x, and is quite efficient since it is short-circuited, meaning it will break (and return True) as soon as it finds the first n that is < 0.
You can also use numpy for vectorized operations
import numpy as np
x = np.array([1.2, -0.4, 3.5,0])
x<=0 # will return the array of boolean values
If you just need to check if the condition met or not then
any(x<=0) # will return true if array contains atleast one True
When using any() or all() the pc will check if the elements in the iterableare True or False. Thus, you need to add a list comprehension to create the iterable:
any([elt < 0 for elt in x])
Basically you need to do the following:
any(value < 0 for value in X)
You can find a detailed explanation here

How can I compare two ordered lists in python?

If I have one long list: myList = [0,2,1,0,2,1] that I split into two lists:
a = [0,2,1]
b = [0,2,1]
how can I compare these two lists to see if they are both equal/identical, with the constraint that they have to be in the same order?
I have seen questions asking to compare two lists by sorting them, but in my specific case, I am not checking for a sorted comparison, but identical list comparison.
Just use the classic == operator:
>>> [0,1,2] == [0,1,2]
True
>>> [0,1,2] == [0,2,1]
False
>>> [0,1] == [0,1,2]
False
Lists are equal if elements at the same index are equal. Ordering is taken into account then.
If you want to just check if they are identical or not, a == b should give you true / false with ordering taken into account.
In case you want to compare elements, you can use numpy for comparison
c = (numpy.array(a) == numpy.array(b))
Here, c will contain an array with 3 elements all of which are true (for your example). In the event elements of a and b don't match, then the corresponding elements in c will be false.
The expression a == b should do the job.

Checking if elements exist in list using python

I am new to python and was wondering if someone could help me out with this. I am trying to see if the elements in b are in a. This is my attempt. Currently I am not getting any output. Any help would be appreciated, thank you!
a = [1]
b = [1,2,3,4,5,6,7]
for each in b:
if each not in a == True:
print(each + "is not in a")
You are testing two different things, and the outcome is False; Python is chaining the operators, effectively testing if (each is in a) and (a == True):
>>> 'a' in ['a'] == True
False
>>> ('a' in ['a']) and (['a'] == True)
False
>>> ('a' in ['a']) == True
True
You never need to test for True on an if statement anyway:
if each not in a:
is enough.
You should be able to just say:
if each not in a:
print ("%d is not in a" % each)
Your actual expression is using operator chaining:
if a > b > c:
parses as:
if (a > b) and (b > c):
in python. which means your expression is actually being parsed as:
if (each not in a) and (a == True):
but a == True will always return False, so that if block will never execute.
a = [1,2,3]
b = [1,2,3,4,5,6,7]
c = [7,8,9]
print set(a) <= set(b) #all elements of a are in b
print set(c) <= set(b) #all elements of c are in b
It is better to see the difference between B and A
set(b).difference(set(a))
You don't need ==True. Just:
if each not in a:
This is really easy using sets:
a = [1]
b = [1, 2]
only_in_b = set(b) - set(a)
# set([2])
Another way:
for bb in b:
try:
a.index(bb)
except:
print 'value is not in the list: ' + str(bb)
I would like to add that if the two lists are large. This is not the best way to do it. Your algorithm is O(n^2). The best way is to traverse a, adding the elements as keys to a dictionary. Afterwards, traverse the second list, checking if the elements are already in the dictionary, this instead is an O(n) algorithm.

Categories

Resources