I have several sorted lists. How can I loop over all elements in sorted order efficiently and elegantly? In my real-life problem, those lists contain elements that are directly comparable and sortable but are different and require different treatment.
I prefer to retain my lists, which is why I copy them manually. If that is missing from a one-liner solution like a library function, I will gladly use that and copy the lists beforehand.
This code does what I want but is neither efficient nor elegant.
from random import randint a: list =  b: list =  c: list =  list_of_lists: list = [a, b, c] for i in range(10): l = randint(0, 2) list_of_lists[l].append(i) print(a, b, c) a_copy = a.copy() b_copy = b.copy() c_copy = c.copy() # print the elements of the lists in sorted order x = a_copy.pop(0) y = b_copy.pop(0) z = c_copy.pop(0) while (x and x is not 1000) or (y and y is not 1000) or (z and z is not 1000): if x is not 1000 and x < y and x < z: print(x) if a_copy and a_copy: x=a_copy.pop(0) else: x = 1000 elif y is not 1000 and y < x and y < z: print(y) if b_copy and b_copy: y=b_copy.pop(0) else: y = 1000 elif z is not 1000 and z < x and z < y: print(z) if c_copy and c_copy: z=c_copy.pop(0) else: z = 1000
Combine them into a single list, and then sort that.
You can use a nested comprehension to flatten the lists as you iterate over them:
>>> a, b, c = [2, 4, 3], [1, 7, 5], [9, 6, 8] >>> sorted(i for x in (a, b, c) for i in x) [1, 2, 3, 4, 5, 6, 7, 8, 9]
or you can just add the lists together:
>>> sorted(a + b + c) [1, 2, 3, 4, 5, 6, 7, 8, 9]
In Python, easiest and quite efficient is to actually just concatenate the list and sort them.
l = [*a, *b, *c] # alternatively, list(chain.from_iterable(list_of_lists)) l.sort()
In theory, this would be
O(n*log(n)), but Python
list.sort() uses a clever sort algorithm called timsort, which are designed to take advantage of runs in the data, such that it would sort a "mostly already sorted lists" — such as concatenation of multiple sorted lists — much faster than theory.
heapq module provides a function to merge sorted iterables into a single sorted iterator.
from heapq import merge merged = list(merge(a, b, c))
>>> a, b, c ([1, 4, 7], [2, 5, 8], [3, 6, 9]) >>> from heapq import merge >>> list(merge(a, b, c)) [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> (a, b, c) ([1, 4, 7], [2, 5, 8], [3, 6, 9])