Страницы: 1
RSS
Вопросы по основам работы со списками в PQ
 
Товарищи, добрый день.
Прошу научения у вас, поскольку немного растерялся. И все вопросы будут связаны со списками.
  1. Не получается научиться работать со списками, включающими в себя вложенные списки:
    Вот, например, такая учебная последовательность:
    Код
    let
        //Создаём пустой список
        #"Результат 001" = {},
        //записываем с список одно значение
        #"Результат 002" = {2},
        //записываем с список одно значение
        #"Результат 003" = {#"Результат 002",1},
        //объединяем списки
        #"Результат 004" = List.Combine({#"Результат 003", #"Результат 002"}),
        //объединяем списки (вариант 2)
        #"Результат 005" = #"Результат 003" & #"Результат 002",
        //проверка списка на пустоту
        #"Результат 006" = List.IsEmpty (#"Результат 001"),
        //объединение списка списков в один список
        #"Результат 007" = List.Union({#"Результат 005",{3..7}}),
    
        Результат = #"Результат 007"
    in
        Результат
    

    ... но в ней всё равно после Union остаётся вложенный список.
    Вопрос, а как объединить всё в одну последовательность. включая все уровни вложений, даже если их несколько.
  2. Создать таблицу из списка с одним столбцом
    Как из списка (объединённого) создать таблицу с одним столбцом?
 
del
Изменено: buchlotnik - 23.08.2021 17:49:28
Соблюдение правил форума не освобождает от модераторского произвола
 
А нельзя ли попросить развёрнутых пояснений по данной строке?
Код
f = (x) =>List.Accumulate(x,{},(s,c)=> if Value.Type(c)=List.Type then s & @f(c) else s & {c}),
 
какого рода пояснения требуются?
идем по списку поэлементно (List.Accumulate), собираем элементы в новый список({}), если элемент не является списком - добавляем его к текущему списку( else s & {c}), в противном случае (if Value.Type( c )=List.Type) рекурсивно вызываем саму  функцию(s & @f( c )) и результат ее выполнения добавляем к текущему списку
Изменено: buchlotnik - 14.11.2020 10:30:49
Соблюдение правил форума не освобождает от модераторского произвола
 
Цитата
buchlotnik написал:
if Value.Type©=List.Type then s & @f© else s & {c}
Может так понятнее будет?
Код
s & (if c is list then @f(c) else {c})
 
Цитата
Андрей VG написал:
Может так понятнее
во всяком случае нагляднее, спасибо  :)
только не уверен, что вопрос в этом - но вариантов без рекурсии как-то в голову не приходит
Соблюдение правил форума не освобождает от модераторского произвола
 
Вроде бы становится лучше в понимании.
Не очень понял роль s в этих выражениях? Соответственно, зачем нужен этот конструкт "s &"?

Второй вопрос касается этой строки:
Код
tbl = Table.FromList(lst, Splitter.SplitByNothing(),{"Один столбец"})

Если следовать инструкции в документации от МелкоМягких, то формула должна быть такой:
Код
tbl = Table.FromList(lst, null,{"Один столбец"})
, но вы используете Splitter.SplitByNothing(). В справке написаны совершенно непонятные слова: "Возвращает функцию, которая не разбивает текст, возвращая свой аргумент как единый список элементов."
Подскажите, пожалуйста, что делает Splitter.SplitByNothing()? Почему Вы используете его?
Изменено: Kirill Gureev - 16.11.2020 01:19:03
 
Цитата
Kirill Gureev написал:
Не очень понял роль s
Вот, для начала и опишите, что делает List.Accumulate так, как вы это поняли. Глядишь, можно будет что-то дельное подсказать.
& - оператор соединения. Для списков, объединяет два списка в один
Код
combo = {1, 2} & {11, 12} // {1, 2, 11, 12}
Изменено: Андрей VG - 16.11.2020 07:43:17
 
Цитата
Kirill Gureev написал:
то формула должна быть такой
да ради бога - я не настаиваю, в той же инструкции упоминается функция разбиения, я предпочитаю указывать ее в явном виде.

UPD - так, стоп - а у вас работает без сплиттера? у меня ругается; как я понимаю без сплиттера будет работать только с текстовыми значениями, что лишний раз подтверждает - указывайте функцию в явном виде, во избежание "сюрпризов"

Цитата
Kirill Gureev написал:
зачем нужен этот конструкт "s &"?
вопрос не понятен, у нас вроде как цель - объединить списки
Изменено: buchlotnik - 16.11.2020 10:54:05
Соблюдение правил форума не освобождает от модераторского произвола
 
Я Table.FromList не использую. Многословная и предназначена чуть для другого. Я так понимаю, как элемент преобразования списка строк с разделителями в таблицу (это же далеко не всегда CSV), поэтому когда строку резать не надо, то и подставляется ничего не делающий Splitter.SplitByNothing(). Вместо него вполне подходит любая функция типа (x)=>x

Более быстрые и дешевые варианты:
Код
Table.FromColumns({Source},{"OneColumn"})
Код
= #table({"OneColumn"}, List.Zip({Source}))

Если пофиг, как называется столбец, а главное получить таблицу, то вот так получим таблицу со столбцом Column1:
Код
Table.FromColumns({Source})
Код
= #table(1, List.Zip({Source}))

а вот так с названным и типизированным столбцом:
Код
Table.FromColumns({Source}, type table [OneColumn = number])
Код
= #table(type table [OneColumn = number], List.Zip({Source}))
F1 творит чудеса
 
Цитата
Kirill Gureev написал:
Не очень понял роль s в этих выражениях?
почитайте тут. Хоть пример с СУММПРОИЗВ и не очень корректный, но суть показывает
F1 творит чудеса
 
Цитата
Kirill Gureev написал:
как объединить всё в одну последовательность. включая все уровни вложений, даже если их несколько.
Цитата
buchlotnik написал:
вроде как цель - объединить списки
если объединить как List.Combine, то можно и &. Если же нужно из {1, {2, 3}} и {{2, 3}, 3, 4} сделать {1,2,3,4}, то тогда  надо List.Distinct в конце натравливать (Combine + Distinct будет гораздо быстрее, чем использовать List.Union в рекурсии)
Изменено: Максим Зеленский - 16.11.2020 14:06:37
F1 творит чудеса
 
Андрей VG, buchlotnik, Максим Зеленский, спасибо Вам большое, что тратите на меня время!
Цитата
Андрей VG написал:
Вот, для начала и опишите, что делает List.Accumulate так, как вы это поняли
Тут, вроде как, и не придумать ничего лишнего.
Код
List.Accumulate({1, 2, 3, 4, 5}, 0, (state, current) => state + current)

"Накапливает сводное значение из элементов в списке {1, 2, 3, 4, 5}, используя выражение ((состояние, текущее значение) => состояние + текущее значение)." (источник). Я так понял, что она ещё и делает это итерационно, смысле, что не просто суммирует, а именно наращивает и прибавляет к результату следующее число.

Цитата
buchlotnik написал:
UPD - так, стоп - а у вас работает без сплиттера?
В том то и дело, что без применения Splitter.SplitByNothing() у меня ничего не получалось (выдавалась ошибка в каждой строке). А что это, я так и не понял. Вы ведь в ней не указываете явно ничего. Как она делит список? Что ещё она умеет делить?

В части s вроде разобрался, но возник вопрос про s & {c}. А почему, собственно, Вы для с явно указываете, что оно должно быть списком, а для s - нет?

Максим Зеленский, c List.Zip я вообще запутался). Проделал примеры на сайте, прочитал комментарий ("Принимает список списков lists и возвращает список списков, объединяя элементы на одной позиции.") - ну вот не очень, если честно, понятно. Масло масленое ... Я был уверен, что list - это и есть список. Я так понял, что он берет все первые элементы - объединяет в список, потом вторы - объединяет... а если в каком-либо списке не хватает элементов - то null.  Но даже осознав это, для меня пока загадка, зачем Вы её применяете.

Цитата
Максим Зеленский написал:
(Combine + Distinct будет гораздо быстрее, чем использовать List.Union в рекурсии)
Не окажите любезность, снабдив примерами?
 
Цитата
Kirill Gureev написал:
Вы ведь в ней не указываете явно ничего
повторяю - я явно указываю "ничего не делать" - это не то же самое, что ничего не сказать
Цитата
Kirill Gureev написал:
почему, собственно, Вы для с явно указываете, что оно должно быть списком, а для s - нет?
потому что s - и так список, а с - нет
Цитата
Kirill Gureev написал:
Масло масленое
Уверены? List.Zip({{1,2,3},{4,5,6}})={{1,4},{2,5},{3,6}} и как ни странно List.Zip({1,2,3})={{1},{2},{3}} а зачем оно так написано в справке по #table:
Цитата
#table(columns as any, rows as any) as any
Изменено: buchlotnik - 17.11.2020 08:11:37
Соблюдение правил форума не освобождает от модераторского произвола
 
Максим Зеленский,
Цитата
Максим Зеленский написал:
если объединить как List.Combine, то можно и &. Если же нужно из {1, {2, 3}} и {{2, 3}, 3, 4} сделать {1,2,3,4}, то тогда  надо List.Distinct в конце натравливать (Combine + Distinct будет гораздо быстрее, чем использовать List.Union в рекурсии)
Я вот попробовал вот такими фразами:
Код
#"Результат 014" =  List.Combine({{1}, {2, 3}}),
#"Результат 015" =  List.Distinct(List.Combine({{1, {2, 3}},{{2, 3}, 3, 4}})),

, но что-то результат получается совсем не тот что я ожидаю.
Вложенные листы остаются, простой список {1, 2, 3, 4} не получается.

Покажите пару примеров, пожалуйста.

buchlotnik,  Вам спасибо.
 
Вот ещё вопрос возник... скорее общее непонимание.
Например, я хочу сделать текстовый список такого рода: Строка 1, Строка 2 и т.д.
Предположим, что у меня есть другой список, который я бы хотел преобразовать в список записей, где наименованием будут те самые строки.

Код
#"Результат 008"={2, 3,5,4,7,23,11},
#"Результат 009"=Number.ToText(each {1..List.Count(#"Результат 008")+1})

Но почему-то выдаётся ошибка.

Вот что не могу понять:
1. Как правильно применять each, какой синтаксис?
2. Как применять функцию к списку?

buchlotnik, Максим Зеленский, Андрей VG, научите, пожалуйста!

В идеале думал получить что-то такое:
Код
Результат = List.Transform(#"Результат 008", each Text.Combine({"Строка ", Number.ToText( each {1..List.Count(#"Результат 008")+1})})),
Изменено: Kirill Gureev - 20.11.2020 02:29:40
 
del
Изменено: buchlotnik - 23.08.2021 17:47:48
Соблюдение правил форума не освобождает от модераторского произвола
Страницы: 1
Наверх