Преобразование списка [ [,],[,],[,] ] в [,,,]

В списке ниже, вторые значения [ ,эти] следуют друг за другом на основе первых значение [эти, ] - 4,4,4,5,5,5,7,7,7,8,8,8 (может быть больше). Как можно получить новый список (new_l) в измененном порядке первых значений 4,5,7,8,4,5,7,8,4,5,7,8 а потом и вовсе их убрать? [убрать эти, ]

l = [[4, -2],
 [4, -1],
 [4, 2],
 [5, -1],
 [5, 1],
 [5, 2],
 [7, 2],
 [7, 1],
 [7, 1],
 [8, 2],
 [8, 2],
 [8, 1]]

Переводим в промежуточный вариант с изменением порядка по первым числам:

l = [[4, -2],
 [5, -1],
 [7, 2],
 [8, 2],
 [4, -1],
 [5, 1],
 [7, 1],
 [8, 2],
 [4, 2],
 [5, 2],
 [7, 1],
 [8, 1]]

Получаем итоговый вариант удаляя ненужные первые значения:

new_l = [-2,-1,2,2,-1,1,1,2,2,2,1,1]

Ответы (3 шт):

Автор решения: asanisimov
from copy import deepcopy

l = [
    [4, -2],
    [4, -1],
    [4, 2],
    [5, -1],
    [5, 1],
    [5, 2],
    [7, 2],
    [7, 1],
    [7, 1],
    [8, 2],
    [8, 2],
    [8, 1]
]


def re_sort(array: list) -> list:
    work_array = deepcopy(array)  # делаем копию списка, то бы не изменять исходный
    last_value = None             # запоминаем последнее значение
    while any(work_array):        # работаем пока есть не пустые элементы
        for i, arr in enumerate(work_array):
            if not arr:           # встретился пустой элемент - ничего не делаем
                continue
            elif last_value != arr[0]:   # если не дублирует предыдущее значение, то выдаем элемент, и на его место ставим None
                last_value = arr[0]
                yield work_array[i] 
                work_array[i] = None
            else:                       # если дублирует предыдущее значние - идем к след элементу
                continue


print([x for x in re_sort(l)])   
# out: [[4, -2], [5, -1], [7, 2], [8, 2], [4, -1], [5, 1], [7, 1], [8, 2], [4, 2], [5, 2], [7, 1], [8, 1]]
res = [x[1] for x in re_sort(l)]
print(res)                      
# out: [-2, -1, 2, 2, -1, 1, 1, 2, 2, 2, 1, 1]

Собственно, по коментариям должно быть все понятно. Логика простая - итерируемся по списку, и если первый элемент не равен предыдущему (сохраняем его значение каждую итерацию) - возвращаем его. Сложность O(n*k), k - максимально кол-во повторяющихся элементов. Первое и самое простое решение, если посидеть, подумать, то думаю кто то лучше напишет.

Пару поправок:

  1. глубокую копию делаем, что бы не менять исходный список, не описано, но возможно он нужен в исходном состоянии.
  2. так как результат конечный - 2-ые элементы вложенных списков, промежуточный список не формирую, а генерирую его элементы. Что бы не забивать память, если большой список придет на вход.
→ Ссылка
Автор решения: CrazyElf

Ну просто нужно правильно посчитать в каком порядке перебирать индексы:

n = 3
l2 = [l[i+j][1] for j in range(n) for i in range(0, len(l), n)]
print(l2)

Вывод:

[-2, -1, 2, 2, -1, 1, 1, 2, 2, 2, 1, 1]
→ Ссылка
Автор решения: MBo
import itertools
l = [[4, -2], [4, -1], [4, 2], [5, -1], [5, 1], [5, 2], [7, 2], [7, 1],
     [7, 1], [8, 2], [8, 2], [8, 1]]
t = []
ll = []
for k, gr in itertools.groupby(l, key = lambda x: x[0]):
    t = []
    for g in gr:
        t.append(g)
    ll.append(t)
res = [x[1] for sub in zip(*ll) for x in sub]
print(res)

[-2, -1, 2, 2, -1, 1, 1, 2, 2, 2, 1, 1]
→ Ссылка