Пусть ll будет списком списков, а tt кортежем кортежей.
Ввод: ll = [["a1","a2"],["b1","b2"],["c1","c2"]]
Желаемый результат: tt = (("a1","b1","c1"),("a2","b2","c2"))
Мне удалось решить это для списка двухэлементных списков, что означает, что внутренний список содержал только два элемента каждый.
def list_of_list_to_tuple_of_tuple(ll):
first_elements = [i[0] for i in ll]
second_elements = [i[1] for i in ll]
new_list = []
new_list.append(tuple(first_elements))
new_list.append(tuple(second_elements))
return tuple(new_list)
ll = [["a1","a2"],["b1","b2"],["c1","c2"]]
list_of_list_to_tuple_of_tuple(ll)
Теперь вопросы:
Есть ли другой способ легко выполнить то, что я сделал?
Есть ли способ легко обобщить этот алгоритм, если у нас есть список из 3 внутренних списков, и каждый внутренний список содержит n элементов? Например:
Ввод: ll = [["a1","a2","a3",..."an"],["b1","b2","b3",..."bn"],["c1","c2","c3",..."cn"]]
Желаемый результат: tt = (("a1","b1","c1"),("a2","b2","c2"),("a3","b3","c3"),...,("an","bn","cn"))
Что касается вашей функции: ее аргумент называется list_
, но вместо этого вы ссылаетесь на ll
. это ошибка
Также обратите внимание, что вы можете писать напрямую result = (tuple(x[0] for x in ll), tuple(x[1] for x in ll))
, а не все эти промежуточные шаги с newlist.append
.
Попробуйте этот однострочный -
tuple(zip(*l))
l = [["a1","a2"],
["b1","b2"],
["c1","c2"]]
tuple(zip(*l))
(('a1', 'b1', 'c1'),
('a2', 'b2', 'c2'))
l2 = [["a1","a2","a3","an"],
["b1","b2","b3","bn"],
["c1","c2","c3","cn"]]
tuple(zip(*l2))
(('a1', 'b1', 'c1'),
('a2', 'b2', 'c2'),
('a3', 'b3', 'c3'),
('an', 'bn', 'cn'))
zip
, как и ожидает того же.zip
объединяет первый, второй, третий... n-й соответствующие элементы каждого подсписка в объект n tuplesИнтуитивно эта операция напоминает транспонирование матрицы. Это легко увидеть, если вы преобразуете свой список списков в массив numpy, а затем выполните транспонирование.
import numpy as np
l = [["a1","a2"],["b1","b2"],["c1","c2"]]
arr = np.array(l)
transpose = arr.T
transpose
array([['a1', 'b1', 'c1'],
['a2', 'b2', 'c2']], dtype='<U2')
headers = [[] for i in range(1, len(ll[0]) + 1)]
for i in ll:
for e in range(0, len(i)):
headers[e].append(i[e])
res = tuple(tuple(sub) for sub in headers)
print(res)
Ваш код легко обобщить более чем на два элемента в подсписках:
ll = [["a1","a2"],["b1","b2"],["c1","c2"]]
first_elements = [x[0] for x in ll]
second_elements = [x[1] for x in ll]
...
kth_elements(k) = [x[k] for x in ll]
Теперь нам просто нужно использовать понимание списка для перебора возможных значений k
:
tt = [[x[k] for x in ll] for k in range(len(ll[0]))]
# [['a1', 'b1', 'c1'], ['a2', 'b2', 'c2']]
Конечно, вы можете получить tt
в виде кортежей вместо списков:
tt = tuple(tuple(x[k] for x in ll) for k in range(len(ll[0])))
# (('a1', 'b1', 'c1'), ('a2', 'b2', 'c2'))
Обратите внимание, что в python уже есть встроенная функция для одновременного перебора нескольких списков, zip
:
tt = tuple(zip(*ll))
# (('a1', 'b1', 'c1'), ('a2', 'b2', 'c2'))
просто сделай это
tuple(zip(*l))
. Подробнее в моем ответе.