Reputation: 47
How do you sort all the values within the nested list structure, so that the sublists are both the same length as in the original list and so that the values shift to the appropriate sublist so that they are sorted overall, not just within each sublist individually. How does one go about this??
for instance:
list1=[[0.10, 0.90, 0,20], [0.15, 0.80], [0.68, 0.08, 0.30]]
Becomes:
list1=[[0.08, 0.10, 0.15], [0.20, 0.30], [0.68, 0.80, 0.90]]
Any help is appreciated
Upvotes: 2
Views: 320
Reputation: 92884
Another variation with itertools
:
import itertools
list1=[[0.10, 0.90, 0.20], [0.15, 0.80], [0.68, 0.08, 0.30]]
sorted_l = sorted(itertools.chain.from_iterable(list1))
result = []
k=0
for i in (len(i) for i in list1):
result.append(sorted_l[k:k+i])
k=k+i
print(result)
The output:
[[0.08, 0.1, 0.15], [0.2, 0.3], [0.68, 0.8, 0.9]]
Upvotes: 0
Reputation: 17263
You can use chain.from_iterable
to chain the lists, sort them and create an iterator. Then you can just iterate over the original lists and create a result using next
:
>>> from itertools import chain
>>> l = [[0.10, 0.90, 0.20], [0.15, 0.80], [0.68, 0.08, 0.30]]
>>> it = iter(sorted(chain.from_iterable(l)))
>>> [[next(it) for _ in l2] for l2 in l]
[[0.08, 0.1, 0.15], [0.2, 0.3], [0.68, 0.8, 0.9]]
Upvotes: 2
Reputation: 13284
I would use itertools
for this and confine the whole thing inside one function:
import itertools
def join_sort_slice(iterable):
it = iter(sorted(itertools.chain(*iterable)))
output = []
for i in map(len, iterable):
output.append(list(itertools.islice(it, i)))
return output
Use it:
lst = [[0.10, 0.90, 0.20], [0.15, 0.80], [0.68, 0.08, 0.30]]
join_sort_slice(lst)
# [[0.08, 0.1, 0.15], [0.2, 0.3], [0.68, 0.8, 0.9]]
The idea is to chain
all sublists together and then sort the outcome. This sorted output is then sliced based on the lengths of the original list of lists.
I hope this helps.
Upvotes: 1
Reputation: 645
Similar to @Evan's answer
import itertools
import numpy as np
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = itertools.tee(iterable)
next(b, None)
return zip(a, b)
list1=[[0.10, 0.90, 0.20], [0.15, 0.80], [0.68, 0.08, 0.30]]
# get the sizes of each of the sublists and where they start
sizes = [len(l) for l in list1]
sizes.insert(0,0)
offsets = np.cumsum(sizes)
# flatten and sort
flat_list = sorted(itertools.chain(*list1))
nested = [flat_list[begin:end] for begin, end in pairwise(offsets)]
print(nested)
Upvotes: 0
Reputation: 2301
This works.
list1=[[0.10, 0.90, 0.20], [0.15, 0.80], [0.68, 0.08, 0.30]]
list_lengths = [len(x) for x in list1]
flattened = [item for items in list1 for item in items]
items_sorted = sorted(flattened)
loc = 0
lists2 = []
for length in list_lengths:
lists2.append(items_sorted[loc:loc+length])
loc += length
print(lists2)
You need to get list lengths at some point to build the final lists2. To get your ordered values properly, you flatten and sort the list, then you add lists to list2 by slicing your sorted items.
Note that this will work for arbitrary length lists and tuples.
Upvotes: 3