How to do logical functions on arrays in python - python

Is it possible somehow to preform logical functions on arrays like eg.
a= [1,2,3,4,5,6]
b= [1,3,5,7]
c= a and b
resulting in c=[1,3,5]
so only the values that are present in both the arrays.
The same with or eg:
d = a OR b
resulting in b=[1,2,3,4,5,6,7]
Is this possible somehow in python or are there short functions for this?
Thanks for your response

Lists do not support logical operations , but you can do it in sets:
a= [1,2,3,4,5,6]
b= [1,3,5,7]
c = list(set(a) | set(b))
d = list(set(a) & set(b))
print(c)
# OUTPUT: [1, 2, 3, 4, 5, 6, 7]
print(d)
# OUTPUT: [1, 3, 5]

You probably should use python set if your collections contain unique values. They are actually mathematical sets: https://en.wikipedia.org/wiki/Set_(mathematics) and support general operation for sets such as intersection and union
>>> a = {1, 2, 3, 4, 5, 6}
>>> b = {1, 3, 5, 7}
>>> c = a.intersection(b)
>>> c
{1, 3, 5}

Here is your snippet:
def and_array(a, b):
return [a[i] for i in range(min(len(a), len(b))) if a[i] in b or b[i] in a]
def or_array(a, b):
return a + [element for element in b if not element in a]
a= [1,2,3,4,5,6]
b= [1,3,5,7]
c = and_array(a, b)
d = or_array(a, b)
print(c)
print(d)
Result:
[1, 2, 3]
[1, 2, 3, 4, 5, 6, 7]
It is not that fast, avoid this for very large lists and use numpy or build-in functions!

Related

Get complement of three lists

I have three lists:
a = [1, 2, 3, 4]
b = [2, 3, 4, 5]
c = [3, 4, 5, 6]
My goal is to get all values which are not present in all of the three lists: [1,2,5,6]
Basically I am searching the "negation" of set(a) & set(b) & set(c).
An efficient solution would be appreciated since the lists are very long.
The opposite of set(a) & set(b) & set(c) is already explained in this question as stated by Chris_Rands in the comments:
>>> (set(a) | set(b) | set(c)) - (set(a) & set(b) & set(c))
{1, 2, 5, 6}
For really long lists, using numpy should be may efficient:
import numpy as np
from functools import reduce
a = [1, 2, 3, 4]
b = [2, 3, 4, 5]
c = [3, 4, 5, 6]
union = reduce(numpy.union1d, (a,b,c))
intersect = reduce(numpy.intersect1d, (a,b,c))
print(numpy.setdiff1d(union, intersect))
Output:
[1 2 5 6]

How to get the expected result using list comprehension

I have the following lists
a=[1,2,3]
b=[4,5,6]
c=[a,b]
i need to combine both list a and b.
result should be like [1,2,3,4,5,6]
i tried with list comprehension
[x for x in i for i in c]
output
[3, 3, 4, 4, 5, 5]
How can i get the result as [1,2,3,4,5,6] using list comprehension.
You can just do:
a + b
If you must use list comprehension:
In [10]: a = [1, 2, 3]
In [11]: b = [4, 5, 6]
In [12]: c = [a, b]
In [13]: [j for i in c for j in i]
Out[13]: [1, 2, 3, 4, 5, 6]
Use itertools.chain.
import itertools
a=[1,2,3]
b=[4,5,6]
c = list(itertools.chain(a, b))
You are concatenating, use + to do so:
c = a + b
If you are concatenating an arbitrary number of lists, use itertools.chain.from_iterable():
from itertools import chain
list_of_lists = [a, b]
c = list(chain.from_iterable(list_of_lists))
Note that if all you need to do is iterate over the concatenation result, you can leave of the list() call altogether.
Do not use sum() for this; that leads to quadratic behaviour as intermediate results are built for every element summed, which takes a full loop.
You can do it with + operation
a = [1, 2, 3]
b = [3, 4, 5]
c = a + b # Equal [1, 2, 3, 3, 4, 5]
Here are 3 different ways you can do it:
>>> a=[1,2,3]
>>> b=[4,5,6]
>>> c=a+b
>>> c
[1, 2, 3, 4, 5, 6]
>>> c=[item for l in [a, b] for item in l]
>>> c
[1, 2, 3, 4, 5, 6]
>>> import itertools
>>> list(itertools.chain(*[a, b]))
[1, 2, 3, 4, 5, 6]

Select unique value in many lists in python

I'd like to select unique value in many lists, but I don't know how to do that:
a = [1,2,3,4,5]
b = [2,3,4,5,6]
c = [5,6,7,8,9]
I'd like to make one new list which is [1,2,3,4,5,6,7,8,9]
I know that using the following could be done, but I am searching quicker way to do that.
for i in (a, b, c):
for j in EachValueInEachList:
NewList.append(j)
list(set(NewList)
By the way, there are thousand of lists in my real program.
Thank you very much.
>>> a = [1,2,3,4,5]
>>> b = [2,3,4,5,6]
>>> c = [5,6,7,8,9]
>>> list(set(a + b + c))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
To avoid creating temporary list, use itertools.chain:
>>> import itertools
>>> list(set(itertools.chain(a, b, c)))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
UPDATE (answer to the comment)
If you have a list of lists, use itertools.chain.from_iterable:
list(set(itertools.chain.from_iterable(a_list_of_lists)))
>>> list(set(a) | set(b) | set(c))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
numpy is best option if long list.
import numpy as np
import time
start_time = time.time()
a = np.array([[1,2,3,4,5], [2,3,4,5,6],[5,6,7,8,9]])
print np.unique(a).tolist()
print time.time() - start_time # Execution time
Output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
0.000999927520752

compare two lists in python and return indices of matched values

For two lists a and b, how can I get the indices of values that appear in both? For example,
a = [1, 2, 3, 4, 5]
b = [9, 7, 6, 5, 1, 0]
return_indices_of_a(a, b)
would return [0,4], with (a[0],a[4]) = (1,5).
The best way to do this would be to make b a set since you are only checking for membership inside it.
>>> a = [1, 2, 3, 4, 5]
>>> b = set([9, 7, 6, 5, 1, 0])
>>> [i for i, item in enumerate(a) if item in b]
[0, 4]
def return_indices_of_a(a, b):
b_set = set(b)
return [i for i, v in enumerate(a) if v in b_set]
For larger lists this may be of help:
for item in a:
index.append(bisect.bisect(b,item))
idx = np.unique(index).tolist()
Be sure to import numpy.
you can do it like this,with no need to set :
a = [1, 2, 3, 4, 5]
b = {9, 7, 6, 5, 1, 0}
[i for i, item in enumerate(a) if item in b]
inspired by #jamylak

Python not all in operation

How do I check if a list is a subset of a bigger list.
i.e.
a = [1,2,3] is a subset of b = [1,2,3,4,5,6]
Can I do something like
if a all in b
http://docs.python.org/library/stdtypes.html#set.issubset
set(a).issubset(set(b))
>>> a = set([1, 2, 3])
>>> b = set([1, 2, 3, 4, 5, 6])
>>> a.issubset(b)
True
or
>>> a = [1, 2, 3]
>>> b = [1, 2, 3, 4, 5, 6]
>>> all(map(lambda x: x in b, a))
True
>>> a = [1, 2, 3, 9]
>>> all(map(lambda x: x in b, a))
False
or (if the number of elements is important)
>>> a = [1, 1, 2, 3]
>>> all(map(lambda x: a.count(x) <= b.count(x), a))
False
mostly like the other answers, but I do prefer the generator syntax here, seems more natural and it's lazily evaluated:
if all(x in b for x in a):
pass
if you care about the number of repeated elements, this option seems nice, and you could optimize it sorting c and using bisect:
def all_in(a, b)
try:
c = b[:]
for x in a: c.remove[x]
return True
except:
return False

Categories