Лучший способ преобразовать список списков в список кортежей?

Каков наилучший способ конвертировать список, такой как [[1,2,3],[a,b,c],[4,5,6]] к списку таких кортежей:

[{1,a,4},{2,b,5},{3,c,6}]

где кортеж N состоит из N-го элемента из каждого из трех подсписков? Должен ли я использовать хвостовую рекурсивную функцию, понимание списка или какой-то другой подход?

4 ответа

Решение

Одно изящное решение может быть

lol2lot([[]|_]) -> [];
lol2lot(LoL) ->
    [ list_to_tuple([hd(L) || L <- LoL]) | lol2lot([tl(L) || L <- LoL]) ].

Просто используйте стандарт lists:zip3/3 функция:

1> [L1,L2,L3] = [[1,2,3],[a,b,c],[4,5,6]].
[[1,2,3],[a,b,c],[4,5,6]]
2> lists:zip3(L1,L2,L3).
[{1,a,4},{2,b,5},{3,c,6}]

Или, если вы предпочитаете не извлекать отдельные списки:

3> apply(lists, zip3, [[1,2,3],[a,b,c],[4,5,6]]).
[{1,a,4},{2,b,5},{3,c,6}]

Я предпочитаю в вашем случае понимание списка, потому что:

  • это короткая строка кода, легко читаемая,
  • ему не нужна вспомогательная функция, поэтому выполненная операция хорошо видна.

    L_of_tuple = [list_to_tuple(X) || X <- L_of_list].

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

Например так:

L =  [[1,2,3],[a,b,c],[4,5,6]].
Size = length(L).
T = [fun(I)->list_to_tuple([lists:nth(I,lists:nth(J,L)) ||J<-lists:seq(1,Size)]) end(I) || I<-lists:seq(1,Size)].
Другие вопросы по тегам