Related
I have two lists I want to merge into one like so:
list_0=[[5], [4], [4], [1], [0], [7], [8], [3], [0]]
list_1=[[0], [9], [6], [4], [5], [9], [5], [9], [3]]
mine_position=[[5], [0], [4], [9], [4], [6], [1], [4], [0], [5], [7], [9], [8], [5], [3], [9], [0], [3]]
The code I have for merging them is:
for i in row:
mine_position.append(i)
mine_position.insert(1, list_1[0])
mine_position.insert(3, list_1[1])
mine_position.insert(5, list_1[2])
mine_position.insert(7, list_1[3])
mine_position.insert(9, list_1[4])
mine_position.insert(11, list_1[5])
mine_position.insert(13, list_1[6])
mine_position.insert(15, list_1[7])
mine_position.insert(17, list_1[8])
I want to shorten it so that the second part can be cleaner, but I can't seem to find a method that works.
You can just zip them together. No loops needed.
list_0=[[5], [4], [4], [1], [0], [7], [8], [3], [0]]
list_1=[[0], [9], [6], [4], [5], [9], [5], [9], [3]]
mine_position = list(zip(list_0, list_1))
We can see that your merged list's elements at even indices consists of elements from list_0 and the odd indices consists of elements from list_1. The below code snippet can be used to generate the merged list.
Code Snippet:
# Original Lists
list_0=[[5], [4], [4], [1], [0], [7], [8], [3], [0]]
list_1=[[0], [9], [6], [4], [5], [9], [5], [9], [3]]
# Merged List
result = []
total_elements = len(list_0) + len(list_1)
# Indices of respective lists
list0_idx = list1_idx = 0
for i in range(total_elements):
if i % 2 == 0:
result.append(list_0[list0_idx])
list0_idx += 1
else:
result.append(list_1[list1_idx])
list1_idx += 1
print(result)
How about this?
list_0=[[5], [4], [4], [1], [0], [7], [8], [3], [0]]
list_1=[[0], [9], [6], [4], [5], [9], [5], [9], [3]]
merged_list = []
for i in range(0, len(list_0)):
merged_list.append(list_0[i])
merged_list.append(list_1[i])
print(merged_list)
It shows this.
[[5], [0], [4], [9], [4], [6], [1], [4], [0], [5], [7], [9], [8], [5], [3], [9], [0], [3]]
You can first create a new variable and assign it as list_0. We do this so that list_0 is not altered. Then use a loop and insert the element of list_1 every 2 elements.
list_0=[[5], [4], [4], [1], [0], [7], [8], [3], [0]]
list_1=[[0], [9], [6], [4], [5], [9], [5], [9], [3]]
merged_list = list_0
idx = 1
for j in list_1:
merged_list.insert(idx,j)
idx += 2
print(merged_list)
#Result: [[5], [0], [4], [9], [4], [6], [1], [4], [0], [5], [7], [9], [8], [5], [3], [9], [0], [3]]
NOTE the reason we increment it by 2, is because at the start of the iteration, a new element will be added into the merged_list.
Using list comprehension:
[item for t in [(list_0[i], list_1[i]) for i in range(len(list_0))] for item in t]
I have a nested list say:
lst = [[1,2,3,4], [2,3,4,5], [3,4,5,6]]
And I would like the output to be:
new_list = [[[1], [2], [3], [4]], [[2], [3], [4], [5]], [[3], [4], [5], [6]]]
this is what i am thinking, but I it is outputting a flat, list of list.
new_lst = []
for i in lst:
i = list(i)
for el in i:
new_list.append([el])
print(new_lst)
I would like to maintain the length of each predefined list in lst
Try List comprehension
[[ [e] for e in l] for l in lst]
You could use list comprehension and append every element to another list.
lst = [[1,2,3,4], [2,3,4,5], [3,4,5,6]]
new = [[[numbers] for numbers in elements] for elements in lst]
The above example adjusts for your desired output.
[[[1], [2], [3], [4]], [[2], [3], [4], [5]], [[3], [4], [5], [6]]]
You can use numpy's reshape np.reshape
>>> import numpy as np
>>> lst = np.array([[1,2,3,4], [2,3,4,5], [3,4,5,6]])
>>> lst
array([[1, 2, 3, 4],
[2, 3, 4, 5],
[3, 4, 5, 6]])
>>> lst.shape
(3, 4)
>>> lst.reshape(3,4,1)
array([[[1],
[2],
[3],
[4]],
[[2],
[3],
[4],
[5]],
[[3],
[4],
[5],
[6]]])
>>> lst.reshape(3,4,1).tolist()
[[[1], [2], [3], [4]], [[2], [3], [4], [5]], [[3], [4], [5], [6]]]
Another version, using recursion (you can have more level of depths in your input):
lst = [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]
def split(i):
if isinstance(i, list):
return [split(v) for v in i]
else:
return [i]
print(split(lst))
Prints:
[[[1], [2], [3], [4]], [[2], [3], [4], [5]], [[3], [4], [5], [6]]]
You could use helper function to have more flexibility later of how you divide the smaller lists. based on an answer from here.
def split_list(alist, wanted_parts=1):
length = len(alist)
return [ alist[i*length // wanted_parts: (i+1)*length // wanted_parts]
for i in range(wanted_parts) ]
lst = [[1,2,3,4], [2,3,4,5], [3,4,5,6]]
ret =[]
for mini_list in lst:
ret.append(split_list(mini_list, len(mini_list)))
I think you had the right idea using multiple for loops. This should work:
list = [[1,2,3,4], [2,3,4,5], [3,4,5,6]]
for i in range(0, 3):
for j in range(0, 4):
(list[i])[j] = [(list[i])[j]]
How can I take a nested List and group it into a tuple of three without importing any module. Please show the expanded for loops so I can understand it better.
For example, I want this nested List. Note this will always multiples of
3 sub lists so there is not a index error.
Thankyou.
[[1], [2], [3], [4], [5], [6], [7], [8], [9]] # Given
[(1, 2, 3), (4, 5, 6), (7, 8, 9)] # Result Wanted
No need for indexes. You can use next() on an iterator even inside a for loop:
xss = [[1], [2], [3], [4], [5], [6], [7], [8], [9]]
it = iter(xss)
answer = []
for x, in it:
answer.append((x, next(it)[0], next(it)[0]))
You can slice with a step size of 3 and zip to make the triples, do a nested unpacking in the for loop, and rebuild the triples without the wrapping lists.
xss = [[1], [2], [3], [4], [5], [6], [7], [8], [9]]
it = zip(xss[::3], xss[1::3], xss[2::3])
answer = []
for [x], [y], [z] in it:
answer.append((x, y, z))
given = [[1], [2], [3], [4], [5], [6], [7], [8], [9]] # because this is a list within a list
output = []
for i in range(0, len(given),3): # step size 3 indicated
temp = (given[i][0], given[i+1][0], given[i+2][0]) # therefore you need the "[0]" behind each given[i]
output.append(temp)
print (output)
I have a Python list and would like to build the ranged loop list. It looks like a ring buffer. So if I have a list:
[[0], [1], [2], [3]]
I would like to get:
[[0], [1], [2], [3]]
[[1], [2], [3], [4]]
[[2], [3], [4], [0]]
[[3], [4], [0], [1]]
[[4], [0], [1], [2]]
I could do it by myself. But is there any better or smarter ways in Python 3?
The code I have tried:
N = 5
d_list = [[_] for _ in range(N)]
for i in range(N):
b1 = i
e1 = i + N - 1
b2, e2 = 0, 0
if e1 >= N:
e2 = e1 - N
print(d_list[b1:e1] + d_list[b2:e2])
what about using a collections.deque and rotate ?
import collections
N = 5
d = collections.deque(range(N))
for _ in range(N):
print(d)
d.rotate(1)
result:
deque([0, 1, 2, 3, 4])
deque([4, 0, 1, 2, 3])
deque([3, 4, 0, 1, 2])
deque([2, 3, 4, 0, 1])
deque([1, 2, 3, 4, 0])
rotate just changes the start of the list, no data is copied/moved, so it's very fast.
note:
you can convert into list if needed
my example is using integers, not lists containing one sole integer. This can be easily adapted if necessary.
This Python function rotates anything slice-able as you desire:
def rotate(l, y=1):
if len(l) == 0:
return l
y = -y % len(l) # flip rotation direction
return l[y:] + l[:y]
>>> rotate([1,2,3,4,5],2)
[4, 5, 1, 2, 3]
>>> rotate([1,2,3,4,5],-22)
[3, 4, 5, 1, 2]
>>> rotate('abcdefg',3)
'efgabcd'
>>> for i in range(N):
... print(d_list)
... d_list=rotate(d_list)
...
[[0], [1], [2], [3], [4]]
[[4], [0], [1], [2], [3]]
[[3], [4], [0], [1], [2]]
[[2], [3], [4], [0], [1]]
[[1], [2], [3], [4], [0]]
Note that in Python 3, range is not sliceable. You first would need to create a list with list(range(...))
The sign convention is the same as deque.rotate
I have the following list:
y = [[0], [0], [0], [0], [1], [1], [1], [1]]
I would like to transpose it and have it in the following form:
[[0]
[0]
[0]
[0]
[1]
[1]
[1]
[1]]
When I did numpy.transpose(y), I got the following:
[[0 0 0 0 1 1 1 1]]
Any ideas?
[[0], [0], [0], [0], [1], [1], [1], [1]]
is exactly the same as this form:
[[0]
[0]
[0]
[0]
[1]
[1]
[1]
[1]]
You had a matrix with 8 rows and 1 column. Transposition executed on the matrix converted it to a matrix with just 1 row and 8 columns, so the output was correct.
If y is a list of lists, it displays as a single line
In [1]: y = [[0], [0], [0], [0], [1], [1], [1], [1]]
In [2]: y
Out[2]: [[0], [0], [0], [0], [1], [1], [1], [1]]
In [3]: print(y)
[[0], [0], [0], [0], [1], [1], [1], [1]]
You could of course do a line by line print
In [4]: for i in y: print(i)
[0]
[0]
[0]
[0]
[1]
[1]
[1]
[1]
If I make an array from it, I get a 2d (n,1) array
In [5]: Y = np.array(y)
In [6]: Y
Out[6]:
array([[0],
[0],
[0],
[0],
[1],
[1],
[1],
[1]])
In [7]: print(Y)
[[0]
[0]
[0]
[0]
[1]
[1]
[1]
[1]]
The array display does show rows and columns. Note that array print does not include commas (but its repr does).
If I transpose it, I get a (1,n) array, which displays as 1 line
In [8]: Y.T
Out[8]: array([[0, 0, 0, 0, 1, 1, 1, 1]])
There 3 different things that you may be confusing - the list, its print or string representation, and an array constructed from the list (and its print).
There is a list version of 'transpose':
In [9]: list(zip(*y))
Out[9]: [(0, 0, 0, 0, 1, 1, 1, 1)]
A longer list of lists may display as you want (if it doesn't neatly fit one line):
In [20]: z=[[i] for i in range(15)]
In [21]: z
Out[21]:
[[0],
[1],
[2],
[3],
[4],
[5],
[6],
[7],
[8],
[9],
[10],
[11],
[12],
[13],
[14]]
Except - that's an ipython pretty print action. In a plain python
shell
>>> [[i] for i in range(15)]
[[0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14]]
Which just emphasizes my point - there's a difference between a list and its print representation.
There is a pprint.pprint (pretty print) that behaves more like ipython, switching to row prints when the list gets too long.