So I have a list like below:
points = [[0, 0], [5, 3], [0, 5], [0, 2], [1, 3], [5, 3]]
I have been using
points.sort(key=lambda pair: pair[0])
to sort the list. But this only sorts it by first value without looking at the second value.
The result of this code is as below:
[[0, 0], [0, 5], [0, 2], [1, 3], [5, 3], [5, 3]]
However, I want to sort is such that the result is:
[[0, 0], [0, 2], [0, 5], [1, 3], [5, 3], [5, 3]]
How do I do it?
Also, while we are at it, how do i remove the duplicates from this list? The final result should be like:
[[0, 0], [0, 2], [0, 5], [1, 3], [5, 3]]
Python already sorts iterable containers (tuples, lists, ...) and strings lexicographically.
>>> points = [[0, 0], [5, 3], [0, 5], [0, 2], [1, 3], [5, 3]]
>>> sorted(points)
[[0, 0], [0, 2], [0, 5], [1, 3], [5, 3], [5, 3]]
import itertools
points = [[0, 0], [5, 3], [0, 5], [0, 2], [1, 3], [5, 3]]
points.sort()
nList = list(points for points,_ in itertools.groupby(points))
print nList
Result:
[[0, 0], [0, 2], [0, 5], [1, 3], [5, 3]]
You can have a sort key that first sorts by the first element x[0], and if their are ties, sort by the second element x[1]:
>>> points = [[0, 0], [5, 3], [0, 5], [0, 2], [1, 3], [5, 3], [0, 4]]
>>> sorted(points, key = lambda x: (x[0], x[1]))
[[0, 0], [0, 2], [0, 4], [0, 5], [1, 3], [5, 3], [5, 3]]
If you don't want any duplicates in this final list, then you can do this:
points = [[0, 0], [5, 3], [0, 5], [0, 2], [1, 3], [5, 3]]
sorted_lst = sorted(points, key = lambda x: (x[0], x[1]))
seen = set()
no_dups = []
for lst in sorted_lst:
curr = tuple(lst)
if curr not in seen:
no_dups.append(lst)
seen.add(curr)
print(no_dups)
# [[0, 0], [0, 2], [0, 5], [1, 3], [5, 3]]
Which has a set seen which keeps track of what sublists have been added, and a list no_dups where the lists get added. If an element is not in seen and add it to the final list, and add it to seen, which indicates that the element has already been added.
Also since type list is not a hashable type, you cannot add them directly to a set. In the above code, the lists are converted to tuples and added to seen, which is a hashable type.
Try itemgetter
from operator import itemgetter
sorted(points, key=itemgetter(0, 1))
Related
So I have this list:
lst = [[7, 0], [4, 4], [7, 1], [5, 0], [6, 1], [5, 2]]
I want to sort it accordingly: in reverse order for the first index, and if 2 items have the same first index, then in normal order by the second index
So the output will be:
lst = [[7, 0], [7, 1], [6, 1], [5, 0], [5, 2], [4, 4]]
I can do this using lambda function:
lst = [[7, 0], [4, 4], [7, 1], [5, 0], [6, 1], [5, 2]]
lst.sort(key = lambda x : (-x[0], x[1]))
But if I dont want to use lambda, how would I do it? I have this template, but not sure how to proceed from here:
lst = [[7, 0], [4, 4], [7, 1], [5, 0], [6, 1], [5, 2]]
def compare(input):
# put code here
lst.sort(key = compare(#what and how do I pass as input))
Python's sort is "stable" so it will keep items with the same sort key in their original relative order. This means that you can perform two sorts, starting with the least significant order and obtain the result you are looking for:
lst = [[7, 0], [4, 4], [7, 1], [5, 0], [6, 1], [5, 2]]
from operator import itemgetter
lst.sort(key=itemgetter(1)) # ascending 2nd index
lst.sort(key=itemgetter(0),reverse=True) # descending 1st index (stable)
print(lst)
[[7, 0], [7, 1], [6, 1], [5, 0], [5, 2], [4, 4]]
If you need to use a custom comparison function, you will find a solution here.
I'd like to know how to sort the lists in the list. However, I don't want to align by key. I'd like to change it according to the following method.
arr = [[2, 3], [5, 1], [4, 1], [5, 3], [4, 2]]
# solution...
I_want_arr = [[2, 3], [1, 5], [1, 4], [3, 5], [2, 4]]
i tried it
for i in arr:
i.sort()
but, it didn't work
using list comprehenstion:
arr = [[2, 3], [5, 1], [4, 1], [5, 3], [4, 2]]
sorted_output = [sorted(l) for l in arr]
using map():
sorted_output = list(map(sorted, arr))
#Gabip's solution includes this and a more time efficient one, check that out first!
How about
arr = [[2, 3], [5, 1], [4, 1], [5, 3], [4, 2]]
I_want_arr = [sorted(x) for x in arr]
This outputs
[[2, 3], [1, 5], [1, 4], [3, 5], [2, 4]]
I have a list having sublists of numbers and want to extract specific ones. In my simplified example I have two main sublists and each one has its own pairs of numbers:
data=[[[1, 0], [2, 0], [2, 1], [2, 2],\
[1, 0], [1, 1], [1, 2],\
[0, 1], [0, 2], [0, 3]],\
[[1, 0], [2, 0],\
[1, 0],\
[0, 1], [0, 2], [1, 2],\
[1, 0], [1, 1], [1, 1]]]
Pairs stored in data can be divided based on some rules and I want the last pair of each division. For simplicity I have shown each division as a row in data. Each division starts with [1, 0] or [0, 1] and these two pairs are break points. Then, simply I want the last pair before each break points. In cases I may have no point between two break points and I only export the previous break point. Finally I want it as the following list:
data=[[[2, 2],\
[1, 2],\
[0, 3]],\
[[2, 0],\
[1, 0],\
[1, 2],\
[1, 1]]]
You can do the following, using enumerate:
def fun(lst):
return [p for i, p in enumerate(lst) if i==len(lst)-1 or set(lst[i+1])=={0,1}]
[*map(fun, data)]
# [[[2, 2], [1, 2], [0, 3]], [[2, 0], [1, 0], [1, 2], [1, 1]]]
fun filters a nested list for all elements that are either last or succeeded by [0, 1] or [1, 0].
data=[[[1, 0], [2, 0], [2, 1], [2, 2],
[1, 0], [1, 1], [1, 2],
[0, 1], [0, 2], [0, 3]],
[[1, 0], [2, 0],
[1, 0],
[0, 1], [0, 2], [1, 2],
[1, 0], [1, 1], [1, 1]]]
newData = []
for subarray in data:
new_subarray = []
for i,item in enumerate(subarray):
if item == [0,1] or item == [1,0]:
if i> 0:
new_subarray.append(subarray[i-1])
if i == len(subarray)-1:
new_subarray.append(item)
newData.append(new_subarray)
print(newData)
Here is a fun little unreadable numpy oneliner:
import numpy as np
[np.array(a)[np.roll(np.flatnonzero(np.logical_or(np.all(np.array(a)==(1, 0), axis=1), np.all(np.array(a)==(0, 1), axis=1)))-1, -1)].tolist() for a in data]
# [[[2, 2], [1, 2], [0, 3]], [[2, 0], [1, 0], [1, 2], [1, 1]]]
It works but in reality you'd better use schwobaseggl's solution.
I'm working with list comprehension but I'm having a trouble working this out, so, I have a 3D list in which I'm trying to obtain pairs in the inner lists, I created a code, in which I can obtain pairs, but it's not exactly what I need, here is my code:
mylist = [[[3, 2, 4, 3], [3, 2, 1], [2, 1]], [[1, 2, 3], [3, 1], [2, 1]]]
res = [[x[idx: idx+2] for i in mylist for x in i for idx in range(0, len(x) - 1)]]
print(res)
#res = [[[3, 2], [2, 4], [4, 3], [3, 2], [2, 1], [2, 1], [1, 2], [2, 3], [3, 1], [2, 1]]]
As you can see, I do get a 3D list with the pairs, but, it's not separated, its just a plain 3D list, I was expecting this:
#Output
res = [[[3, 2], [2, 4], [4, 3], [3, 2], [2, 1], [2, 1]], [[1, 2], [2, 3], [3, 1], [2, 1]]]
# ^
# Here is the separation
I'm working on my list comprehension, but I can't see where is happening the problem, I believe there is something wrong with the bracket, but I been trying different combinations but nothing seems to work, so any help will be appreciated.
Also, maybe this is bit of a stretch, but there is some way I can eliminate some repeated inner list in the 3D list, I mean, using res to get:
newres = [[[3, 2], [2, 4], [4, 3], [2, 1]], [[1, 2], [2, 3], [3, 1], [2, 1]]]
#[3, 2], [2, 1] eliminated
If you can point me to the right direction that would be great, thank you so much!
[[x[idx: idx+2] for x in i for idx in range(0, len(x) - 1)] for i in mylist ]
Sorry that I am not good at writing nested loops in one line. But this will remove duplicates and creates a 3D list with pairs:
mylist = [[[3, 2, 4, 3], [3, 2, 1], [2, 1]], [[1, 2, 3], [3, 1], [2, 1]]]
res = []
for inner in mylist:
temp = []
for each in inner:
for e in zip(each, each[1:]):
if list(e) not in temp:
temp.append(list(e))
res.append(temp)
print(res) # [[[3, 2], [2, 4], [4, 3], [2, 1]], [[1, 2], [2, 3], [3, 1], [2, 1]]]
This question already has an answer here:
sort a 2D list first by 1st column and then by 2nd column
(1 answer)
Closed 2 years ago.
I have a list like this
[[2, 1], [0, 3], [1, 2], [2, 5], [1, 4]]
So i want to sort this list according to 1st element, but if 1st element of 2 items are equal then sort according to 2nd element and i want to do it in reverse order(decreasing order)
i used this
arr.sort(key=lambda x: x[0], reverse=True)
but its result is
[[2, 1], [2, 5], [1, 2], [1, 4], [0, 3]]
I want result something like this
[[2, 5], [2, 1], [1, 4], [1, 2], [0, 3]]
you can do it like so :
a = [[2, 1], [0, 3], [1, 2], [2, 5], [1, 4]]
a.sort(key= lambda x:x[0])
a.reverse()
print(a)
reverse=True on .sort() reverse the list but the items with same value are not sorted.
or simpler
a = sorted(a, key=lambda x: (x[0],x[1]), reverse=True)
You can try this code:
ls = [[2, 1], [0, 3], [1, 2], [2, 5], [1, 4]]
ls_sorted = sorted(ls, key=lambda x: (x[0],x[1]), reverse=True)
print(ls_sorted)
Output:
[[2, 5], [2, 1], [1, 4], [1, 2], [0, 3]]