Transposing the list - python

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.

Related

How to delete list inside nested list based on count?

import time
dc = []
def u():
for i in range(10):
if i < 5:
dc.append([i])
print(dc)
time.sleep(10)
while True:
u()
output after 1st run:[[0], [1], [2], [3], [4]]
output after 2nd run:[[0], [1], [2], [3], [4], [0], [1], [2], [3], [4]]
output for 3rd run:
[[0], [1], [2], [3], [4], [0], [1], [2], [3], [4], [0], [1], [2], [3], [4], [0], [1], [2], [3], [4]]
output for 4th run:
[[0], [1], [2], [3], [4], [0], [1], [2], [3], [4], [0], [1], [2], [3], [4], [0], [1], [2], [3], [4], [0], [1], [2], [3], [4]]
I want to delete the values from first iteration after 5 loops and keep the 2nd set of values until it reaches 5 loops.
How can I do this?
One way would be tracking the length of each list inserted, and then removing that number. Also your data makes no sense, since each item is also in it's own list, which is nonsensical.
x = [0], [1], [2], [3], [4]
y = [0], [1], [2], [3], [4]
dc = []
itemLengths = []
dc.extend(x)
itemLengths.append(len(x))
dc.extend(y)
itemLengths.append(len(y))
print(dc)
print(dc[itemLengths.pop(0):])
or a better way to handle this:
class U:
def __init__(self):
self.dc = []
self.insertLength = []
def add(self, data):
self.dc.extend(data)
self.insertLength.append(len(data))
self.remove()
return self
def remove(self):
if len(self.insertLength) == 6:
self.dc = self.dc[self.insertLength.pop(0):]
return self
def wait(self, timer):
time.sleep(10)
u = U()
u.add(x)
u.add(y)
u.add(x)
u.add(x)
u.add(x)
u.add(x)
print(u.insertLength)
print(len(u.insertLength))
print(u.dc)

Making each element of a nested list a list

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]]

Removing opposite lists from list of lists

I need to remove from a list of lists all the opposite couples of lists. For example, if my list of lists is l = [[1], [-1], [-1], [2], [2], [2], [-2]], and I need to remove the couple of opposite lists, the output should be l_out = [[-1], [2], [2]], because I remove a [1], [-1] and a [2], [-2]. How can I do this procedure recursively with a loop?
from collections import Counter
l = [[1], [-1], [-1], [2], [2], [2], [-2]]
c = Counter(v for (v, ) in l)
out = [[v] for v in c for _ in range(c.get(v, 0)-c.get(-v, 0))]
print(out)
Prints;
[[-1], [2], [2]]
So, to do this efficiently, you can keep track of the opposite in a dict along with the index it was encountered. When building up the resulting list, use None to mark spots that need to be deleted, and just do a second pass to filter out nones, making keeping track of the indices much easier:
In [1]: data = [[1], [-1], [-1], [2], [2], [2], [-2]]
In [2]: seen = {}
In [3]: result = []
...: default = 0, None
...: for i, (x,) in enumerate(data): # again, why single lists?
...: n, j = seen.get(-x, default)
...: if n == 0:
...: seen[-x] = 1, i
...: result.append([x])
...: elif n == 1:
...: seen[-x] = 0, i
...: result.append(None)
...: result[j] = None
...:
In [4]: result
Out[4]: [[1], None, None, None, None, [2], [-2]]
In [5]: [x for x in result if x is not None]
Out[5]: [[1], [2], [-2]]
So, this is still linear time, albeit, using auxiliary, linear space.
You could pop from the back as well.
l = [[1], [-1], [-1], [2], [2], [2], [-2]]
i = len(l)-1
if i%2==0:
i=i-1
while i>0:
l.pop(i)
i-=2
print(l)

Subtract corresponding elements from 2 lists that both contain column matrices

I have 2 lists
A= matrix([[ 9],
[5],
[7],
[ 8]]), matrix([[2],
[3],
[7],
[8])]
B = matrix([[ 3],
[2],
[1],
[ 4]]), matrix([[2],
[3],
[2],
[5])]
I want subtract the first matrix in the second list B from the first matrix in the first list A. To get the matrix
matrix([[3],
[3],
[6],
[4])
then the second from the second, and add these new matrices to a new list C.
I tried the code
C=list()
for j in A :
for k in B:
C.append(j-k)
But it's not giving the correct answers . What are your suggestions?

Python list range access as a ring buffer

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

Categories

Resources