Преобразование списка [ [,],[,],[,] ] в [,,,]
В списке ниже, вторые значения [ ,эти] следуют друг за другом на основе первых значение [эти, ] - 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 шт):
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 - максимально кол-во повторяющихся элементов. Первое и самое простое решение, если посидеть, подумать, то думаю кто то лучше напишет.
Пару поправок:
- глубокую копию делаем, что бы не менять исходный список, не описано, но возможно он нужен в исходном состоянии.
- так как результат конечный - 2-ые элементы вложенных списков, промежуточный список не формирую, а генерирую его элементы. Что бы не забивать память, если большой список придет на вход.
Ну просто нужно правильно посчитать в каком порядке перебирать индексы:
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]
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]