LINUX.ORG.RU

Как превратить линейный список в список списков (таблицу)?

 


0

1

Есть список строк:

list1 = '''1
первое название
2:23
автор такой-то
2
следующее название
1:09
автор сякой-то'''.split('\n')

(Разумеется, строк гораздо больше.) Нужно превратить его в «таблицу»:

[['1', 'первое название',   '2:23', 'автор такой-то'],
 ['2', 'следующее название', '1:09', 'автор сякой-то']]

Желательно список списков, а не список кортежей, чтобы было проще менять элементы. Число строк кратно 4, либо можно отбросить лишние.

Почти сразу нашёл в сети красивое решение:

list2 = list( zip( * [iter(list1)] * 4 ) )

которое даёт именно список кортежей. Можно сделать

list2 = [ list(_) for _ in zip( * [iter(list1)] * 4 ) ]

Но как-то некрасиво.

Более правильные решения есть?

Ответ-однострочник:

list2 = list( map( list, zip( * [iter(list1)] * 4 ) ) )
★★★★★

Последнее исправление: question4 (всего исправлений: 2)

Более правильным будет поменять формат входных данных, если это возможно. Такие выборки по 4 элемента это жуткая жуть, одна лишняя пустая строка в середине и все превращается в тыкву.

Кроме \n есть еще много разделителей;-)

А так генератор конечно же, вариантов много, это же питон.

AntonI ★★★★
()
Ответ на: комментарий от AntonI

поменять формат входных данных

Копируется вручную с веб-страницы, извлекается pyperclip-ом.

лишняя пустая строка в середине

Не бывает. А вот нечисловой текст в 1-й колонке встречается.

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

Не бывает.

Ну тогда лишний элемент (один). Все что может испортиться - портится. В общем контроль делимости на четыре я бы как минимум вставил.

А вот нечисловой текст в 1-й колонке встречается.

Это как раз небольшая проблема. Если это обработка ручной копипасты, то скрипт может спрашивать что делать в интерактиве в таких случаях.

AntonI ★★★★
()
Ответ на: комментарий от Shadow

Одна из самых медленных вещей в мире - обычные циклы в python.

Есть вещи ещё медленнее. В этом цикле можно добавлять по 1 элементу в питоновский список.

question4 ★★★★★
() автор топика
Ответ на: комментарий от Shadow

Звучит странно, но оптимальным вариантом будет чуть ли не создание numpy матрицы с помощью генератора, итерирующего по списку.

Средствами numpy задача решается элементарно.

np.array(list1)[:len(list1) - len(list1) % 4].reshape(len(list1)//4,4)

Можно даже присвоить имена столбцам, только тогда придётся руками выставить длины строк.

Но мне сейчас интереснее узнать о других способах.

question4 ★★★★★
() автор топика