Two Slices for Nested List - python

There is one nested list [[1, 1], [2, 2], [3, 3], [4,4]].
I would like to iterate the list by three slices. I belong to [0, 3], j=i-1, k=i-2
For example:
slice 1: [3, 3], [4, 4]
slice 2: [2, 2], [3, 3]
slice 3: [1, 1], [2, 2]
How can I do it?

You can try this:
s = [[1, 1], [2, 2], [3, 3], [4,4]]
new_s = {"slice {}".format(len(s)-i-1):[s[i], s[i+1]] for i in range(len(s)-1)}
Output:
{'slice 1': [[3, 3], [4, 4]], 'slice 3': [[1, 1], [2, 2]], 'slice 2': [[2, 2], [3, 3]]}

Using zip() you can create that output like:
Code:
new_data = list(zip(reversed(data[:-1]), reversed(data)))
Test Code:
data = [[1, 1], [2, 2], [3, 3], [4, 4]]
new_data = list(zip(reversed(data[:-1]), reversed(data)))
print(new_data)
And if you want a dict from that:
new_data = {'slice_{}'.format(i): d for i, d in
enumerate(zip(reversed(data[:-1]), reversed(data)), 1)}
print(new_data)
Results:
[([3, 3], [4, 4]), ([2, 2], [3, 3]), ([1, 1], [2, 2])]
{'slice_1': ([3, 3], [4, 4]), 'slice_2': ([2, 2], [3, 3]), 'slice_3': ([1, 1], [2, 2])}

Related

How to get number of rows with a unique column value (grouped by an other column value)?

Consider the following array:
x = np.array([[1, 1],[1, 1], [1, 2], [1, 2], [1, 2],
[2, 3], [2, 3], [2, 3], [2, 4], [2, 4]])
x
Out[12]:
array([[1, 1],
[1, 1],
[1, 2],
[1, 2],
[1, 2],
[2, 3],
[2, 3],
[2, 3],
[2, 4],
[2, 4],
[2, 5],
[2, 5],
[2, 5]])
How would I get the number of unique column 2 values for each column 1 value?
For example: if it can be done using a function V, then V(x) = [2, 3].
I have implemented this using a for loop. However, it seems more complicated than necessary and takes too much time (when applied to my actual dataset which is much larger than this example).
I am interested in performance and am willing to sacrifice code clarity for speed (although they usually are directly correlated!).
Use numpy.unique twice:
import numpy as np
x = np.array([[1, 1],[1, 1], [1, 2], [1, 2], [1, 2],
[2, 3], [2, 3], [2, 3], [2, 4], [2, 4]])
# drop duplicates
xx = np.unique(x, axis=0)
# count the first column
values, counts = np.unique(xx[:,0], return_counts=True)
print(values)
print(counts)
# [1, 2]
# [2, 2]

Need to partition a list into parts following a specific rule

I have the following list of lists (the inner lists will be referred to as tuples henceforth, just to avoid confusion) :
[[1, 1], [2, 1], [2, 2], [3, 1], [3, 2], [4, 1], [3, 3], [4, 2], [5, 1], [4, 3], [5, 2], [6, 1], [4, 4], [5, 3], [6, 2], [7, 1]]
and I would like to create another list that contains:
[[[1, 1]], [[2, 1], [2, 2]], [[3, 1], [3, 2]], [[4, 1], [3, 3], [4, 2]], [[5, 1], [4, 3], [5, 2]], [[6, 1], [4, 4], [5, 3], [6, 2]], [[7, 1]]]
What basically I am doing is scanning the list of tuples, and putting the tuples into sublists until I hit a tuple that has a higher first coordinate than the previous tuples (italics is a correction based on a comment, I had meant this but while writing, missed it). For example the first element is [1,1] and the next is [2,1], but since 2>1, the first sublist is [[1,1]]. Then again, when we hit [3,1], the second sublist created is [[2,1],[2,2]] and so on.
How do I implement this in python? Specifically python 3?
The following solution assumes that the input data is never an empty list:
d = [[1, 1], [2, 1], [2, 2], [3, 1], [3, 2], [4, 1], [3, 3], [4, 2], [5, 1], [4, 3], [5, 2], [6, 1], [4, 4], [5, 3], [6, 2], [7, 1]]
d2 = [[d[0]]]
for t in d[1:]:
if t[0] > d2[-1][0][0]:
d2.append([t])
else:
d2[-1].append(t)
print(d2)
The following accommodates the case where the input data is an empty list:
d2 = []
for t in d:
if (not d2) or (t[0] > d2[-1][0][0]):
d2.append([t])
else:
d2[-1].append(t)
a = [[1, 1], [2, 1], [2, 2], [3, 1], [3, 2], [4, 1], [3, 3], [4, 2], [5, 1], [4, 3], [5, 2], [6, 1], [4, 4], [5, 3], [6, 2], [7, 1]]
def cummax(v):
x = v[:1]
for i in v:
x.append(x[-1] if x[-1] > i else i)
return x
d = {}
for i,j in zip(cummax([i for i,j in a]), a):
if not d.get(i):
d[i]=[]
d[i].append(j)
list(d.values())
[[[1, 1]], [[2, 1], [2, 2]], [[3, 1], [3, 2]], [[4, 1], [3, 3], [4, 2]], [[5, 1], [4, 3], [5, 2]], [[6, 1], [4, 4], [5, 3], [6, 2]], [[7, 1]]]

How do I sort a nested list by the second value and then the first, without using packages? [duplicate]

This question already has answers here:
Python sorting by multiple criteria
(2 answers)
Closed 2 years ago.
I have a nested list of pairs of numbers:
>>> l = [[0, 0], [1, 3], [3, 2], [3, 4], [4, 6], [5, 2], [3, 1], [1, 6], [5, 4], [4, 3], [2, 5], [3, 0]]
Is it possible to sort the list by the second term and then the first without using packages?
The desired output is this:
>>> sort_two_then_one(l)
[[0, 0], [3, 0], [3, 1], [3, 2], [5, 2], [1, 3], [4, 3], [3, 4], [5, 4], [2, 5], [1, 6], [4, 6]]
Here is the answer:
Code
lst = [[0, 0], [1, 3], [3, 2], [3, 4], [4, 6], [5, 2], [3, 1], [1, 6], [5, 4], [4, 3], [2, 5], [3, 0]]
sorted_list = sorted(sorted(lst, key=lambda x: x[0]), key=lambda x: x[1])
print(sorted_list)
Output
[[0, 0],
[3, 0],
[3, 1],
[3, 2],
[5, 2],
[1, 3],
[4, 3],
[3, 4],
[5, 4],
[2, 5],
[1, 6],
[4, 6]]
Seems to be a duplicate of Python sorting by multiple criteria
sorted(l, key=lambda x: (x[1], x[0]))
>>> [[0, 0], [3, 0], [3, 1], [3, 2], [5, 2], [1, 3], [4, 3], [3, 4], [5, 4], [2, 5], [1, 6], [4, 6]]
You can use the optional key argument of sorted() and implement a lambda function. These are all built-in methods of python. See also this
a=[[0, 0], [1, 3], [3, 2], [3, 4], [4, 6], [5, 2], [3, 1], [1, 6], [5, 4], [4, 3], [2, 5], [3, 0]]
print(sorted(a, key = lambda x: x[1]))
output
[[0, 0], [3, 0], [3, 1], [3, 2], [5, 2], [1, 3], [4, 3], [3, 4], [5,
4], [2, 5], [4, 6], [1, 6]]
[Program finished]

Expanding a vector to a new size

Given a vector, for example
my_list=[1, 2, 3]
how to expand each entry to a new matrix (seen as a multidimensional list or, more likely, a numpy array)?
For example, in the case of matrix being a numpy array of size 2x2 matrix, the output, expanded_my_list, would be:
[[[1, 1], [1, 1]], [[2, 2], [2, 2]], [[3, 3], [3, 3]]]
or as a numpy array:
array([[[1, 1],
[1, 1]],
[[2, 2],
[2, 2]],
[[3, 3],
[3, 3]]])
where expanded_my_list.shape is (3,2,2).
One solution may be:
for i in range(len(my_list)):
expanded[:, i] = my_list[i].expand_as(matrix[:, i])
my_list = [1, 2, 3]
[[[e] * 2 for _ in range(2)] for e in my_list]
output:
[[[1, 1], [1, 1]], [[2, 2], [2, 2]], [[3, 3], [3, 3]]]
You could use numpy.tile().
By creating additional axis via np.newaxis and repeating the elements of the list along these axis you can create your wanted result:
import numpy as np
lst = [1, 2, 3]
arr = np.array(lst)
arr2 = np.tile(arr[:, np.newaxis, np.newaxis], reps=(1, 2, 2))
# Output:
# array([[[1, 1],
# [1, 1]],
# [[2, 2],
# [2, 2]],
# [[3, 3],
# [3, 3]]])
lst2 = arr2.tolist() # If a nested list is required
Or more general:
arr = np.array([[1, 2],
[3, 4]])
expanded_shape = (3, 4)
arr2 = np.tile(arr.reshape(arr.shape + (1,)*len(expanded_shape)),
reps=(1,)*arr.ndim + expanded_shape)
# Output, shape (2, 2, 3, 4)
# array([[[[1, 1, 1, 1],
# [1, 1, 1, 1],
# [1, 1, 1, 1]],
# [[2, 2, 2, 2],
# [2, 2, 2, 2],
# [2, 2, 2, 2]]],
# [[[3, 3, 3, 3],
# [3, 3, 3, 3],
# [3, 3, 3, 3]],
# [[4, 4, 4, 4],
# [4, 4, 4, 4],
# [4, 4, 4, 4]]]])

List recursion?

I wrote a function:
def expandList(aList):
"""expand a list"""
finalList = []
for j in aList:
tempList = []
if type(j) != type(list):
tempList.append(j)
finalList.extend(tempList)
else:
finalList.extend(expandList(j))
return finalList
to expand nested list within themselves like:
[[1, [2, 3], [3, 2]], [2, [1, 3], [3, 1]], [3, [1, 2], [2, 1]]]
into:
[[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]]
or
[[1, [2, [3, 4], [4, 3]], [3, [2, 4], [4, 2]], [4, [2, 3], [3, 2]]],
[2, [1, [3, 4], [4, 3]], [3, [1, 4], [4, 1]], [4, [1, 3], [3, 1]]],
[3, [1, [2, 4], [4, 2]], [2, [1, 4], [4, 1]], [4, [1, 2], [2, 1]]],
[4, [1, [2, 3], [3, 2]], [2, [1, 3], [3, 1]], [3, [1, 2], [2, 1]]]]
into:
[[1, 2, 3, 4],[1, 2, 4, 3],[1, 3, 2, 4],
[1, 3, 4, 2],[1, 4, 3, 2],[1, 4, 2, 3],[2, 1, 3, 4],
[2, 1, 4, 3],[2, 3, 1, 4],[2, 3, 4, 1],[2, 4, 1, 3],
[2, 4, 3, 1],[3, 1, 2, 4],[3, 1, 4, 2],[3, 2, 1, 4],
[3, 2, 4, 1],[3, 4, 1, 2],[3, 4, 2, 1],[4, 1, 2, 3],
[4, 1, 3, 2],[4, 2, 1, 3],[4, 2, 3, 1],[4, 3, 1, 2],
[4, 3, 2, 1]]
and so forth. I wish to be able to do this in any size of nested lists.
My function doesn't seem to work right. What am I doing wrong? How can I fix/improve my function?
Thank you in advance
First of all using following command is a wrong way for checking the list type :
type(j) != type(list)
because type(list) returns <type 'type'> actually you are getting the type of a type object that is a type.
In edition you don't need to loop over your sub list and using extend method although you used it incorrect.Since your numbers are in the first index you can just convert it to list and append the rest to it.
You can use a simple list comprehension :
>>> [[[i[0]]+j for j in i[1:]] for i in l]
[[[1, 2, 3], [1, 3, 2]], [[2, 1, 3], [2, 3, 1]], [[3, 1, 2], [3, 2, 1]]]

Categories