list comprehension to create list of list - python

What is the list comprehension to achieve this:
a=[1,2,3,4,5]
b=[[x,False] for x in a]
will give,
[[1,False],[2,False],[3,False],[4,False],[5,False]]
How can I get True for some number in the list? I need something like this:
[[1,False],[2,False],[3,False],[4,True],[5,False]]
My random playing has not solved the problem.

Use if-else conditional:
>>> a = [1,2,3,4,5]
>>> b = [[x, True if x == 4 else False] for x in a]
>>> b
[[1, False], [2, False], [3, False], [4, True], [5, False]]
or just:
>>> b = [[x, x == 4] for x in a]

Maybe this?
b=[[x, x==4] for x in a]

>>> a = [1, 2, 3, 4, 5]
>>> b = [[x, x==4] for x in a]
>>> b
[[1, False], [2, False], [3, False], [4, True], [5, False]]
>>>
This takes advantage of the fact that x==4 will return True if x is equal to 4; otherwise, it will return False.

Use the ternary operator to choose different values based on conditions:
conditional_expression ::= or_test ["if" or_test "else" expression]
Example:
>>> [[x,False if x%4 else True] for x in a]
[[1, False], [2, False], [3, False], [4, True], [5, False]]

Related

Boolean indicies of extended slice

I have the following numpy array:
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
I can use extended slicing to select e.g. columns:
>>> a[:,0::2]
array([[1, 3],
[4, 6],
[7, 9]])
>>> a[:,1::2]
array([[2],
[5],
[8]])
But I want to produce the following:
array([[True, False, True],
[True, False, True],
[True, False, True]])
array([[False, True, False],
[False, True, False],
[False, True, False]])
import numpy as np
bools = np.array([[False, False, False],
[False, False, False],
[False, False, False]])
bools[:, 0::2] = True
print(bools)
Output:
[[ True False True]
[ True False True]
[ True False True]]
np.array([[True if y%2==0 else False for y,z in enumerate(x)] for x in bools])
np.array([[False if y%2==0 else True for y,z in enumerate(x)] for x in bools])
Explanation:
By using list comprehension, variable 'x' iterates through each row of a. The inner list comprehension iterates through each of this('x' from outer comprehension) list elements. It can be observed that in your output, True & False values depend on index of the elements rather than the element values. Hence by using enumerate(), we get the index of each element in 'y' & value in 'z'. And using conditions on 'y', we decide on replacing with True or False

Element-wise in-operator between two arrays

I'm wondering if there is a nice and elegant way to do an element-wise in comparison between two arrays.
arr1 = [[1, 2],
[3, 4],
[5, 6]]
àrr2 = [3,
5,
6]
result = arr2 in arr1
Now I want a result like :
[False, False, True]
Thanks a lot in advance!
Edit: I'm sorry, my example was a bit misleading. I want this to be performed element-wise, meaning I want to check, whether arr2[0] is in arr1[0], arr2[1] is in arr2[1] and so on.. I updated the example
Also the real arrays are much larger, so I would like to do it without loops
You can use operator.contains:
>>> arr1 = [[1, 2], [4, 5], [7, 8]]
>>> arr2 = [3, 4, 7]
>>> list(map(contains, arr1, arr2)
[False, True, True]
Or for numpy use np.isin
>>> arr1 = np.array([[1, 2], [4, 5], [7, 8]])
>>> arr2 = np.array([3, 4, 7])
>>> np.isin(arr2, arr1).any(1)
[False True True]
IIUC, there is the wonderful np.in1d to do this:
In [16]: np.in1d(arr2, arr1)
Out[16]: array([False, True, True])
From the docs, this function does the following:
Test whether each element of a 1-D array is also present in a second array.
comprehension and zip
[a in b for a, b in zip(arr2, arr1)]
[False, False, True]
You can do print([any(x in arr2 for x in a) for a in arr1])
Can be done with a list comprehension
result = [arr2[i] in arr1[i] for i in range(len(arr1))]
Then you have
[False, True, True]
Here's a quick way:
for i in zip(arr2,arr1):
print(i[0] in i[1])

Check if a value from a nested list is in anothere nested list

I want to check if list1[0] value is contained in list2[0] and then list1[1] -> list2[1] ... so I get the same result as below:
list1 = [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
list2 = [[2, 5], [4, 6, 8], [4]]
result = [[False, True, False], [False, False, True], [False, True, False]]
You can use nested list comprehensions:
result = [[x in b for x in a] for a, b in zip(list1, list2)]
print(result)
Output:
[[False, True, False], [False, False, True], [False, True, False]]

Python: Get indices of common values in 3 sorted arrays

I have three sorted arrays:
>>> a = arange(10)
>>> b = arange(3,12)
>>> c = arange(-2,8)
>>> print(a)
[0 1 2 3 4 5 6 7 8 9]
>>> print(b)
[ 3 4 5 6 7 8 9 10 11]
>>> print(c)
[-2 -1 0 1 2 3 4 5 6 7]
I want to get a list of the indices of the elements of each array that are contained in all of the other arrays as well.
In this example, it would be the indices in each array that correspond to the numbers 3 - 7
so something like:
a_inds, b_inds, c_inds = get_unq_inds(a,b,c)
a_inds = [3,4,5,6,7] (or [False, False, False, True, True, True, True, True, False, False])
b_inds = [0,1,2,3,4] (or [True, True, True, True, True, False, False, False, False])
etc
Basically, I want to expand the solution provided here:
(Find indices of common values in two arrays)
to 3 arrays. (Or, if you're feeling ambitious, 'n' arrays)
You can do this:
def get_unq_inds(a, b, c):
uniq_vals = list(set(a).intersection(b).intersection(c))
return [a.index(x) for x in uniq_vals], [b.index(x) for x in uniq_vals], [c.index(x) for x in uniq_vals]
# you can use this for boolean values
#return [x in uniq_vals for x in a], [x in uniq_vals for x in b], [x in uniq_vals for x in c]
OUTPUT
a_inds, b_inds, c_inds = get_unq_inds(range(9), range(3,12), range(-2,8))
>>> a_inds, b_inds, c_inds
([3, 4, 5, 6, 7], [0, 1, 2, 3, 4], [5, 6, 7, 8, 9])
OUTPUT for boolean values :
[False, False, False, True, True, True, True, True, False]
[True, True, True, True, True, False, False, False, False]
[False, False, False, False, False, True, True, True, True, True]
Live demo here
You could combine all your ranges to get the common elements in a set and then test against this:
>>> ranges = [range(9), range(3,12), range(-2,8)]
>>> s = set.intersection(*map(set,ranges))
>>> [[i for i,x in enumerate(sublist) if x in s] for sublist in ranges]
[[3, 4, 5, 6, 7], [0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
This will work for any number of input lists.
Or similarly using the same s with #Ashish Ranjan's idea (note the indices may not be ordered though because we are iterating over the unordered set(), although in practise they are likely to maintain the order due to the way Python hash's integers):
[[sublist.index(x) for x in s] for sublist in ranges]
For a list of booleans, you can use a list comprehension.
a_inds = [x in b and x in c for x in a]

multidimensional numpy array __eq__

I have a bi-dimensional np.array like
x = np.array([[1,2], [4,5], [4,6], [5,4], [4,5]])
now I want the indices where x is equal to [4,5] (-> [1, 4]). The operator == works in a different way:
x == [4,5]
array([[False, False],
[ True, True],
[ True, False],
[False, False],
[ True, True]], dtype=bool)
but I want something like [False, True, False, False, True]. Is it ok to do an and?
Usually the array is very big and I have to do it a lot of times, so I need a very fast way.
this should be the numpy-way:
x = np.array([[1,2], [4,5], [4,6], [5,4], [4,5]])
(x == [4,5]).all(1)
#out: array([False, True, False, False, True], dtype=bool)
No prior experience with numpy, but this works for a standard array:
x = [[1, 2], [4, 5], [4, 6], [5, 4], [4, 5]]
indices = [i for i, v in enumerate(x) if v == [4, 5]]
# gives [1, 4]
matches = [v == [4, 5] for v in x]
# gives [False, True, False, False, True]

Categories