Comprehension with chained for statements - python

So I am supposed to take an array x and an array y, and make a new array of pairs such that the elements are not equal. Here is my code:
x=[1,2,3,4]
y=[2,4,6]
my_list=[]
for a in x:
for b in y:
if a!=b:
list=[a,b]
my_list.append(list)
#my_list+=[(a,b) for (a,b) in (x,y) if (a!=b)]
print (my_list)
Thus, the output is: [[1, 2], [1, 4], [1, 6], [2, 4], [2, 6], [3, 2], [3, 4], [3, 6], [4, 2], [4, 6]]
Without importing anything, how do I collapse this with list comprehension AND chained for statements. My meager attempt is in the #comment section.

Here's how you can do it using a list comprehension:
x=[1,2,3,4]
y=[2,4,6]
[[a,b] for a in x for b in y if a!=b]
Output
[[1, 2], [1, 4], [1, 6], [2, 4], [2, 6], [3, 2], [3, 4], [3, 6], [4, 2], [4, 6]]

You can also avoid creating x and y variables by writing the following code
[[i, j] for i in [1, 2, 3, 4] for j in [2, 4, 6] if i != j]

This is also a where you can make use of itertools to build the output. Gets you the same output as a list comprehension, but with a little less code.
import itertools
x=[1,2,3,4]
y=[2,4,6]
list(itertools.product(x, y))

Related

Appending elements with similar index in Python

I want to append elements of A (shape=(1,10,2)) with the same j to create a new array A1. For example, [1,3] and [2,3] should be appended into one element because of same j (=3) and different i (=1 and =2 respectively). The desired output is attached.
import numpy as np
A=np.array([[
[0, 1],
[0, 2],
[1, 3],
[2, 3],
[2, 4],
[3, 5],
[3, 6],
[4, 6],
[5, 7],
[6, 7]]])
The desired output is
A1=array([[
[0, 1],
[0, 2],
[[1, 3],[2, 3]],
[2, 4],
[3, 5],
[[3, 6],[4, 6]],
[[5, 7],[6, 7]]]])
A1.shape=(1,7,2)
I've done it using the following steps. The only problem is that you can't have the final result as an array because of varying sizes. If you convert the result to a numpy array it becomes an array of lists of shape (7,).
You can however still iterate through it with for loops if it's not a huge list.
If you are using it in neural networks, you might want to consider converting to a ragged tensor
Get the list of second numbers
second_numbers = A[:,:,1].reshape(-1)
Get unique values from that list
uniq = set(second_numbers)
Create new list based on those unique values
new_list = []
for i in uniq:
new_list.append((A[:, second_numbers == i, :].reshape(-1,2)).tolist())
Full code with result:
second_numbers = A[:,:,1].reshape(-1)
uniq = set(second_numbers)
new_list = []
for i in uniq:
new_list.append((A[:, second_numbers == i, :].reshape(-1,2)).tolist())
new_list
>>> [[[0, 1]],
[[0, 2]],
[[1, 3], [2, 3]],
[[2, 4]],
[[3, 5]],
[[3, 6], [4, 6]],
[[5, 7], [6, 7]]]

How to populate (append) list in Python with elements, that appear multiple of 2 times

Let's say I have a list of of list of 2 elements [[1 , 2], ...] in Python. Now I need to get something like this:
[2, 2] [2, 3] [3, 4] [3, 5] [3, 6] [3, 7]
Second element always goes up by 1, first element too, but occurs 2^n (n>=1) times, before going up.
So next will be 8 lists with first element 4, which occurs 8 times, second element of the lists will go up from 8 to 15.
Maybe you can try nested for loops like below
def fn(n, x):
for i in range(2, n+1):
for j in range(2**(i-1), 2**i):
x.append([i, j])
return(x)
or
from math import log2,ceil
def fn(n,x):
[x.append([ceil(log2(i)),i-1]) for i in range(3,2**n+1)]
return(x)
such that
>>> fn(3, [[1,2]])
[[1, 2], [2, 2], [2, 3], [3, 4], [3, 5], [3, 6], [3, 7]]
>>> fn(4, [[1,2]])
[[1, 2], [2, 2], [2, 3], [3, 4], [3, 5], [3, 6], [3, 7], [4, 8], [4, 9], [4, 10], [4, 11], [4, 12], [4, 13], [4, 14], [4, 15]]
from math import log
initial_list = [[1,2]]
def extend_pattern(initial_list,n):
last_sublist = initial_list[-1]
first_element = last_sublist[0]
for i in range(n):
last_sublist = list(last_sublist)
if i != 0:
last_sublist[1] += 1
last_sublist[0] = first_element + int(log(i+2,2))
initial_list.append(last_sublist)
extend_pattern(initial_list,10)
print(initial_list)
#[[1, 2], [2, 2], [2, 3], [3, 4], [3, 5], [3, 6], [3, 7], [4, 8], [4, 9], [4, 10], [4, 11]]
Sounds like a fun homework.
If you intend a function with an output like this:
[[1, 1], [2, 2], [2, 3], [3, 4], [3, 5], [3, 6], [3, 7], [4, 8], [4, 9], [4, 10]]
then this
def populate(n):
left=1
right=1
temp=right*2
output=[]
for i in range(0,n):
output.append([left,right])
right+=1
if(right==temp):
left+=1
temp=right*2
return output
is one of plenty ways to do it.
If you meant starting with a list and n something like this should work:
def populate(inputlist,n):
left=inputlist[len(inputlist)-1][0]+1
right=inputlist[len(inputlist)-1][1]+1
temp=right*2
for i in range(0,n):
inputlist.append([left,right])
right+=1
if(right==temp):
left+=1
temp=right*2
return inputlist

How to add a value in a nested list that corresponding to another list?

I'm setting up a linear connection and I have two list:
a = [1,1,1,2,2,3,3,3,4]
b = [1,3,7,2,3,4,7,8,9]
a[i] related to b[i]
I regrouped b as c:
c = [[1, 3], [7], [2, 3], [4], [7, 8], [9]]
I tried to add the corresponding value of a in every sublist in c to get:
d = [[1, 1, 3], [1, 7], [2 ,2, 3], [3, 4], [3, 7, 8], [4, 9]]
The first value in every sublist of c that originally in b is related to a like c[0][0] = b[0], and add a[0] to c[0], c[1][0] = b[2], so add a[2] to c[1].
If sublist in c and the first value of the sublist = b[i], add a[i] to every sublist.
I got stuck for this.
You could build an iterator from a and take successive slices of it using itertools.islice in order to consume it according to the length of the sublists in c, but only select the first item from each slice:
from itertools import islice
a = [1,1,1,2,2,3,3,3,4]
c = [[1, 3], [7], [2, 3], [4], [7, 8], [9]]
a_ = iter(a)
[[list(islice(a_, len(j)))[0]] + [i for i in j] for j in c]
Output
[[1, 1, 3], [1, 7], [2, 2, 3], [3, 4], [3, 7, 8], [4, 9]]
Another method. Basic Way.
#!/bin/python
a = [1,1,1,2,2,3,3,3,4]
b = [1,3,7,2,3,4,7,8,9]
c = [[1, 3], [7], [2, 3], [4], [7, 8], [9]]
#d = [[1, 1, 3], [1, 7], [2 ,2, 3], [3, 4], [3, 7, 8], [4, 9]]
element_count=0
d=[]
for x in c:
print (a[element_count])
print(x)
d.append([a[element_count]]+x)
element_count+=len(x)

List with 2 elements, a list and an int, want to relate every list item with that int

I have a list of lists in which every element of the first list is composed of a second list and an integer.
What I want to do is relate that single integer with every element in the list, thus making the elements of the first list be lists of 2 elements the code. I haven't got a clue on how to do this.
This is the code i'm using to test this:
list1 = [[1,2,3],[1,2,3,4]]
list2 = []
list3 = []
for element in range (len(list1)):
list2.append(list1[element][0])
list2.append(list3)
list3.append([list1[element][1:]])
list3[element].append(list1[element][0])
print(list3)
A simple approach for your first example:
l = [1,[2,3]]
final_l = [[l[0], i] for i in l[-1]]
Output:
[[1, 2], [1, 3]]
A solution for a larger example:
l = [[1,[2,3]], [3, [45, 2]], [6, [12, 2]], [3, [3, 4]]]
final_l = [[[c, a] for c in b] for a, b in l]
Output:
[[[2, 1], [3, 1]], [[45, 3], [2, 3]], [[12, 6], [2, 6]], [[3, 3], [4, 3]]]
Try this:
list2 = [[[l[0], num] for num in l[1:]] for l in list1]
The output is:
list2 = [[[1, 2], [1, 3]], [[1, 2], [1, 3], [1, 4]]]
You can try in one line with this approach:
l = [[1,[2,3]], [3, [45, 2]], [6, [12, 2]], [3, [3, 4]]]
print(list(map(lambda x:list(map(lambda y:[y,x[0]],x[1])),l)))
output:
[[[2, 1], [3, 1]], [[45, 3], [2, 3]], [[12, 6], [2, 6]], [[3, 3], [4, 3]]]

List dimensionality after appending two lists

If I have two 2-dimensional lists, how do I append one to the other, such that the final list is still 2-dimensional?
For example:
x = [[1, 2], [3, 4]]
y = [[5, 6], [7, 8]]
x.append(y)
print x
Prints out:
[[1, 2], [3, 4], [[5, 6], [7, 8]]]
However, I want it to be:
[[1, 2], [3, 4], [5, 6], [7, 8]]
Append makes new items within a list. Extend is what you are looking for:
x = [[1, 2], [3, 4]]
y = [[5, 6], [7, 8]]
x.extend(y)
print x
result:
[[1, 2], [3, 4], [5, 6], [7, 8]]
Simply add them:
x = [[1, 2], [3, 4]]
y = [[5, 6], [7, 8]]
z = x + y
print z
Yields
[[1, 2], [3, 4], [5, 6], [7, 8]]

Categories