Find If Lista Contains Any Elements Not in Listb

Python find elements in one list that are not in the other

TL;DR:

SOLUTION (1)

import numpy as np
main_list = np.setdiff1d(list_2,list_1)
# yields the elements in `list_2` that are NOT in `list_1`

SOLUTION (2) You want a sorted list

def setdiff_sorted(array1,array2,assume_unique=False):
ans = np.setdiff1d(array1,array2,assume_unique).tolist()
if assume_unique:
return sorted(ans)
return ans
main_list = setdiff_sorted(list_2,list_1)



EXPLANATIONS:

(1) You can use NumPy's setdiff1d (array1,array2,assume_unique=False).

assume_unique asks the user IF the arrays ARE ALREADY UNIQUE.
If False, then the unique elements are determined first.

If True, the function will assume that the elements are already unique AND function will skip determining the unique elements.

This yields the unique values in array1 that are not in array2. assume_unique is False by default.

If you are concerned with the unique elements (based on the response of Chinny84), then simply use (where assume_unique=False => the default value):

import numpy as np
list_1 = ["a", "b", "c", "d", "e"]
list_2 = ["a", "f", "c", "m"]
main_list = np.setdiff1d(list_2,list_1)
# yields the elements in `list_2` that are NOT in `list_1`


(2)
For those who want answers to be sorted, I've made a custom function:

import numpy as np
def setdiff_sorted(array1,array2,assume_unique=False):
ans = np.setdiff1d(array1,array2,assume_unique).tolist()
if assume_unique:
return sorted(ans)
return ans

To get the answer, run:

main_list = setdiff_sorted(list_2,list_1)

SIDE NOTES:

(a) Solution 2 (custom function setdiff_sorted) returns a list (compared to an array in solution 1).

(b) If you aren't sure if the elements are unique, just use the default setting of NumPy's setdiff1d in both solutions A and B. What can be an example of a complication? See note (c).

(c) Things will be different if either of the two lists is not unique.

Say list_2 is not unique: list2 = ["a", "f", "c", "m", "m"]. Keep list1 as is: list_1 = ["a", "b", "c", "d", "e"]
Setting the default value of assume_unique yields ["f", "m"] (in both solutions). HOWEVER, if you set assume_unique=True, both solutions give ["f", "m", "m"]. Why? This is because the user ASSUMED that the elements are unique). Hence, IT IS BETTER TO KEEP assume_unique to its default value. Note that both answers are sorted.

pythonnumpy

Check if one list contains element from the other

If you just need to test basic equality, this can be done with the basic JDK without modifying the input lists in the one line

!Collections.disjoint(list1, list2);

If you need to test a specific property, that's harder. I would recommend, by default,

list1.stream()
.map(Object1::getProperty)
.anyMatch(
list2.stream()
.map(Object2::getProperty)
.collect(toSet())
::contains)

...which collects the distinct values in list2 and tests each value in list1 for presence.

Check if something is (not) in a list in Python

The bug is probably somewhere else in your code, because it should work fine:

>>> 3 not in [2, 3, 4]
False
>>> 3 not in [4, 5, 6]
True

Or with tuples:

>>> (2, 3) not in [(2, 3), (5, 6), (9, 1)]
False
>>> (2, 3) not in [(2, 7), (7, 3), "hi"]
True

Check if list contains element different from something

For the bare boolean check, you can do sth fancy like this, using map and any:

for lst in (a, b, c):
print(any(map("_".__ne__, lst)))
# False
# True
# True

Or be a little more explicit:

any(x != "_" for x in lst)

any has the advantage of short-circuiting (stopping at the first hit) as compared to your suggested set length approach:

len(set(lst)) > 1

If that makes it faster in the real world depends on your data. If most your lists are only underscores and therefore iterated in their entirety, the set conversion (C-optimized) may well be faster.

Using any() and all() to check if a list contains one set of values or another

Generally speaking:

all and any are functions that take some iterable and return True, if

  • in the case of all, no values in the iterable are falsy;
  • in the case of any, at least one value is truthy.

A value x is falsy iff bool(x) == False.
A value x is truthy iff bool(x) == True.

Any non-boolean elements in the iterable are perfectly acceptable — bool(x) maps, or coerces, any x according to these rules:

  • 0, 0.0, None, [], (), [], set(), and other empty collections are mapped to False
  • all other values are mapped to True.

The docstring for bool uses the terms 'true'/'false' for 'truthy'/'falsy', and True/False for the concrete boolean values.


In your specific code samples:

You’ve slightly misunderstood how these functions work. The following does something completely different from what you thought:

if any(foobars) == big_foobar:

...because any(foobars) would first be evaluated to either True or False, and then that boolean value would be compared to big_foobar, which generally always gives you False (unless big_foobar coincidentally happened to be the same boolean value).

Note: the iterable can be a list, but it can also be a generator or a generator expression (≈ lazily evaluated/generated list), or any other iterator.

What you want instead is:

if any(x == big_foobar for x in foobars):

which basically first constructs an iterable that yields a sequence of booleans—for each item in foobars, it compares the item to the value held by big_foobar, and (lazily) emits the resulting boolean into the resulting sequence of booleans:

tmp = (x == big_foobar for x in foobars)

then any walks over all items in tmp and returns True as soon as it finds the first truthy element. It's as if you did the following:

In [1]: foobars = ['big', 'small', 'medium', 'nice', 'ugly']                                        

In [2]: big_foobar = 'big'

In [3]: any(['big' == big_foobar, 'small' == big_foobar, 'medium' == big_foobar, 'nice' == big_foobar, 'ugly' == big_foobar])
Out[3]: True

Note: As DSM pointed out, any(x == y for x in xs) is equivalent to y in xs but the latter is more readable, quicker to write and runs faster.

Some examples:

In [1]: any(x > 5 for x in range(4))
Out[1]: False

In [2]: all(isinstance(x, int) for x in range(10))
Out[2]: True

In [3]: any(x == 'Erik' for x in ['Erik', 'John', 'Jane', 'Jim'])
Out[3]: True

In [4]: all([True, True, True, False, True])
Out[4]: False

See also: http://docs.python.org/2/library/functions.html#all

How to check if a list contains all the elements of another list INCLUDING duplicates

Repeated calls to list.count (for the same list) are very inefficient. You can use collections.Counter and how it implements differences:

from collections import Counter

def contains(l1, l2):
return not (Counter(l2) - Counter(l1))

>>> contains(["A", "A", "A", "b", "b"], ["A", "A", "b", "b"])
True
>>> contains(["a", "a", "b"], ["a", "b"])
True
>>> contains(["a", "b"], ["a", "a", "b"])
False
>>> contains(["a", "a", "b"], ["a", "b", "c"])
False

Check if listt contains any of another list

You could use a nested Any() for this check which is available on any Enumerable:

bool hasMatch = myStrings.Any(x => parameters.Any(y => y.source == x));

Faster performing on larger collections would be to project parameters to source and then use Intersect which internally uses a HashSet<T> so instead of O(n^2) for the first approach (the equivalent of two nested loops) you can do the check in O(n) :

bool hasMatch = parameters.Select(x => x.source)
.Intersect(myStrings)
.Any();

Also as a side comment you should capitalize your class names and property names to conform with the C# style guidelines.

How to check in javascript if a list contains any element?

In javascript there are no lists but arrays, and you can check their length property

if(serialNumberList.length > 0) { 
// Do your stuff
}

Finding elements not in a list

Your code is not doing what I think you think it is doing. The line for item in z: will iterate through z, each time making item equal to one single element of z. The original item list is therefore overwritten before you've done anything with it.

I think you want something like this:

item = [0,1,2,3,4,5,6,7,8,9]

for element in item:
if element not in z:
print(element)

But you could easily do this like:

[x for x in item if x not in z]

or (if you don't mind losing duplicates of non-unique elements):

set(item) - set(z)


Related Topics



Leave a reply



Submit