Списки и статистика
Список объединяет несколько значений под одним именем: например, шаги за неделю, экзаменационные оценки или расходы за месяц. После этого можно найти сумму, среднее, меру разброса и выбрать нужные значения.
Здесь описаны запись списков и доступ по индексу, сводная статистика, суммирование строк выше, группировка строк тегами, сортировка и срезы, преобразование через map и filter, а также арифметика целых списков. Страница пригодится для обработки набора чисел. Списки строк могут представлять матрицы; им посвящена отдельная страница.
Создание списка
Поместите значения в квадратные скобки, разделенные запятыми:
scores = [72, 85, 91, 64, 88] даёт [72, 85, 91, 64, 88]scores[0] даёт 72scores[4] даёт 88length(scores) даёт 5Позиция значения в списке — его индекс. Он записывается в квадратных скобках после списка. Индексы начинаются с нуля: scores[0] — первая оценка, а scores[4] — пятая. Индекс последнего элемента всегда равен length(scores) - 1. Отрицательный, дробный или слишком большой индекс вызывает ошибку; отсчёт с конца отрицательными индексами не поддерживается.
Элементами могут быть расчеты, величины с единицами или другие списки:
[2 * 45, 60 + 15] даёт [90, 75][1.5 kg, 750 g] даёт [1.5 kg, 750 g][[1, 2], [3, 4]][1][0] даёт 3При вложенных списках первый индекс выбирает внутренний список, а второй выбирает из него значение: [1] выбирает [3, 4], затем [0] выбирает 3.
Внутри списка работают разделители тысяч, поэтому числа можно вставлять в привычной записи. После запятой между значениями ставьте пробел. Запятая, за которой идут три цифры без пробела, остаётся частью числа:
salaries = [£32,000, £41,500, £38,250] даёт [£32,000.00, £41,500.00, £38,250.00]average(salaries) даёт £37,250.00Несколько вещей, на которые нужно обратить внимание:
- Без пробелов запятые разделяют значения:
[8200,10400]содержит два элемента. Запись[100,200,300]может означать одно число или три, поэтому Varlig выдаёт ошибку с пояснением обоих вариантов. - В результатах отображаются разделители тысяч и пробелы после запятых между элементами. Поэтому
[8,200, 10,400]— список из двух значений. - Список содержит не более 1024 значений.
Сводная статистика
scores = [72, 85, 91, 64, 88]sum(scores) даёт 400average(scores) даёт 80median(scores) даёт 85min(scores) даёт 64max(scores) даёт 91count(scores) даёт 5mean и avg - это другие имена для average, total для sum, stdev для stddev и count для length, поэтому привычки электронной таблицы переносятся. product умножает значения вместе. Наиболее распространенное значение, процентиль или квартиль, см. ниже.
С помощью именованного списка вы также можете написать статистику словами:
scores = [72, 85, 91, 64, 88]average of scores даёт 80total of scores даёт 400sum of, mean of, median of, min of, max of и count of работают одинаково. После of напишите имя или сами значения, разделенные запятыми, с круглыми скобками или без них. Для значений в квадратных скобках используйте форму функции, как в average([72, 85, 91]).
Большая часть статистики, включая sum, product, average, median, min, max, count и stddev, также принимает отдельные значения вместо списка:
max(72, 85, 91) даёт 91sum(1, 2, 3, 4) даёт 10average of 70, 85, 91 даёт 82mean of (1,2,3) даёт 2average(1,200, 1,800) даёт 1,500Сложение строк выше
Строка, содержащая только sum, total, subtotal, grand total, average, max или min, вычисляет соответствующий показатель по результатам выше. Область начинается после предыдущего итога, разделителя --- или заголовка #. Так каждая часть заметки получает свой результат по мере ввода. Это соответствует параметру Subtotal в контекстном меню строки:
# Groceriesbread = £1.20milk = £1.45eggs = £2.30total даёт £4.95# Householdbin bags = £3.50washing up liquid = £1.80total даёт £5.30К слову итога можно добавить подпись, присвоить ему имя, перевести результат в другую единицу или дописать комментарий — строка останется естественной частью заметки:
tickets = £64train = £41.20Estimated total: total даёт £105.20est = total хранит число под именем, а total // still to book добавляет рядом заметку. total in kg преобразует его перед отображением, что удобно, когда в разделе используются граммы и килограммы. Статистическое слово рядом с оператором указывает на число, которое бы отображало сама строка, поэтому £5 + subtotal добавляет пять в текущий общий итог.
# Parcels12 kg даёт 12 kg4 kg даёт 4 kg850 g даёт 850 gtotal in kg даёт 16.85 kgmax даёт 12 kgЕсли вы присвоили собственное значение имени sum или total, строка покажет именно его. Если выше нет подходящих величин, появляется Unsupported: no amounts above to add up, а не пустое место или ноль. Частая причина — заголовок, о котором вы забыли.
Каждая сумма подсчитывается один раз. Когда более поздняя строка в разделе вырабатывает что-то из названной суммы, общая сумма учитывает эту строку, а не обе, поэтому список покупок цен за единицу и количества складывается в то, что вы на самом деле заплатите:
shirt = £18.50shorts = £99 * shirt даёт £166.5010 * shorts даёт £90.00fee = £40vat = fee * 20% даёт £8.00total даёт £304.50shirt и shorts засчитываются внутри двух линий, которые их используют, в то время как fee остается в общей сумме, потому что vat занимает только часть.
Это правило прослеживает цепочку имён до конца. Если сумма делится на доли, а затем доли снова складываются, учитываются и строка их сложения, и исходная сумма:
pot = £9001st = 50% of pot даёт £450.002nd = 30% of pot даёт £270.003rd = 20% of pot даёт £180.001st + 2nd + 3rd даёт £900.00total даёт £900.00Складываются только совместимые величины. Если выше есть деньги или величины с единицами, проценты, ставки и простые количества исключаются, как и строки с ошибками. Числа без валюты, вставленные столбцом, учитываются, если записаны с денежной точностью до сотых. Значения с большим числом десятичных знаков, например курс или коэффициент, исключаются. Подсказка итога перечисляет пропущенные строки, например «Пропущена строка 3 (people = 2)» или «Пропущена строка 2 (ошибка)», чтобы было видно, что вошло в сумму.
Список из двух или более сумм, написанных без названий, прямо над общей суммой и под строкой, выработанной из имен, добавляется самостоятельно. Таким образом, бюджет, разработанный в верхней части заметки, больше не учитывается в списке ниже:
budget = £18,000remaining = budget - £6,388.25 даёт £11,611.75- skip hire £250 даёт £250.00- deep clean £120 даёт £120.00subtotal даёт £370.00Для суммирования несоседних строк пометьте их тегом.
Наиболее частые значения
Функция mode возвращает единственное наиболее частое значение, а modes — список всех значений, разделяющих максимальную частоту:
marks = [3, 4, 4, 5, 5, 5, 6]mode(marks) даёт 5modes([1, 1, 2, 2, 3]) даёт [1, 2]Функция mode даёт результат, только если одно значение встречается строго чаще остальных. Если повторов нет или несколько значений имеют одинаковую максимальную частоту, она сообщает об этом, а не выбирает одно:
mode([1, 2, 3]) даёт Unsupported: No value repeats, so this list has no mode; use median or average insteadПроцентили и квартили
Функция percentile(list, rank) принимает процентиль от 0 до 100 и возвращает значение в этой позиции с интерполяцией между двумя ближайшими наблюдениями. quartile(list, k) делает то же по четвертям, с k от 0 до 4: quartile(list, 1) равнозначно percentile(list, 25):
scores = [72, 85, 91, 64, 88]percentile(scores, 50) даёт 85percentile(scores, 25) даёт 72quartile(scores, 3) даёт 88quartile(scores, 4) даёт 91percentile([1, 2, 3, 4], 25) даёт 1.75quartile([1, 2, 3, 4], 3) даёт 3.2550-й процентиль - это медиана, а 0-й и 100-й - quartile(list, 0) и quartile(list, 4) - это наименьшие и самые большие значения, такие же, как min и max. Ранг за пределами своего диапазона - это ошибка, а не ближайшее значение, которое подойдет:
percentile([1, 2, 3, 4], 101) даёт Unsupported: A percentile is between 0 and 100quartile([1, 2, 3, 4], 5) даёт Unsupported: A quartile is 0, 1, 2, 3 or 4Разброс: дисперсия и стандартное отклонение
scores = [72, 85, 91, 64, 88]variance(scores) даёт 132.5stddev(scores) to 1 dp даёт 11.5Обе функции вычисляют выборочные показатели: делят на число значений минус один (n - 1). Это обычный вариант, если данные являются выборкой из большей совокупности. Нужно как минимум два значения. Для округления добавьте после любой статистической функции to 1 dp.
Если список содержит всю генеральную совокупность, а не выборку, используйте соответствующие функции: они делят на n и принимают даже одно значение:
# Train delays in minutesdelays = [2, 4, 4, 4, 5, 5, 7, 9]sample_variance(delays) даёт 4.5714285714population_variance(delays) даёт 4sample_stddev(delays) даёт 2.1380899353population_stddev(delays) даёт 2| Вызов | На что делится сумма квадратов отклонений | Минимум значений |
|---|---|---|
variance, sample_variance |
n - 1 |
Два значения |
population_variance |
n |
Одно значение |
stddev, stdev, sample_stddev |
n - 1 |
Два значения |
population_stddev |
n |
Одно значение |
Имена sample_variance и sample_stddev — полные варианты variance и stddev, явно указывающие выборочный расчёт. Короткие имена всегда означали и продолжают означать выборочные показатели.
Списки с единицами
Функции sum, average, median, mode, modes, percentile, quartile, min, max, stddev и population_stddev сохраняют единицы и переводят совместимые друг в друга. Все значения приводятся к единице первого элемента; результат возвращается в ней же:
commutes = [24 min, 31 min, 27 min, 22 min]sum(commutes) даёт 1 hour 44 minaverage(commutes) даёт 26 minmedian(commutes) даёт 25.5 minpercentile(commutes, 25) даёт 23.5 minpopulation_stddev(commutes) даёт 3.3911649916 minsum([1 kg, 500 g]) даёт 1.5 kgmodes([1 kg, 500 g, 1 kg, 500 g]) даёт [0.5 kg, 1 kg]Дисперсии — исключение: при возведении наблюдений в квадрат единицы здесь не сохраняются. Поэтому функции дисперсии принимают только числа без единиц измерения.
sample_variance([1 kg, 2 kg]) даёт Unsupported: A variance squares its observations, so it takes plain numbers; use stddev for amounts with a unitФункция sort тоже работает только с числами без единиц. Статистика по несовместимым величинам, например sum([1 kg, 3 m]), вызывает ошибку, а не молча пропускает значения.
Правила точности описаны в разделе Гарантии вычислительного движка.
Пустые списки
| Вызов для пустого списка | Результат |
|---|---|
sum([]) |
0 |
product([]) |
1 |
count([]), length([]) |
0 |
average([]), median([]), min([]), max([]) |
Ошибка |
variance([]), stddev([]) |
Ошибка |
Пустой список часто получается после filter, которому ничего не подошло. Поэтому average отфильтрованного списка может выдать ошибку, даже если исходный список не пуст.
Теги
Тег - это # со словом, соединенным прямо с ним, например, #food. Напишите одну в любом месте на строке, чтобы пометить эту строку. Тег не принимает участия в сумме, поэтому строка все еще показывает свой собственный ответ, и она группирует эту строку с каждой другой строкой, несущей один и тот же тег. total of #food затем добавляет эти строки:
£12.50 lunch #food даёт £12.50£8 coffee #food даёт £8.00flights = £420 #trip даёт £420.00total of #food даёт £20.50Теги позволяют суммировать несоседние строки, в отличие от обычного промежуточного итога. Расходы за неделю, поездка и покупки могут находиться в одном блоке, каждый со своей суммой внизу. Наведите указатель на тег, чтобы увидеть текущий итог.
Каждая статистика работает на теге. of не является обязательным, тег может быть до или после слова, и ответ принимает метку или собственное имя, как и любая другая строка:
#food £12.50#food £8£420 #triptotal of #food даёт £20.50average of #food даёт £10.25count of #food даёт 2min of #food даёт £8.00max of #food даёт £12.50#food total даёт £20.50Food this week: sum of #food даёт £20.50eaten = avg #food даёт £10.25sum, total, average, avg, mean, count, min и max все читаются таким образом.
Статистика по тегу используется как обычная сумма в дальнейшем выражении. Так можно вычесть уже внесённый платёж, умножить итог или сравнить два тега:
£20 shop #food даёт £20.00£30 meal out #food даёт £30.00total of #food - £10 даёт £40.002 * total of #food даёт £100.00Cooking kit: total of #food даёт £50.00У строки может быть несколько тегов; каждый учитывает её. Укажите два тега в одном выражении, чтобы выбрать только строки с обоими:
£50 dinner #trip #food даёт £50.00£30 taxi #trip даёт £30.00£9 sandwich #food даёт £9.00total of #trip даёт £80.00total of #food даёт £59.00total of #trip #food даёт £50.00Что входит в сумму по тегу
Выражение с тегом просматривает те же строки, что и обычный total, и следует тем же правилам:
- Оно охватывает свой раздел до предыдущего итога, разделителя
---или заголовка#. - Складываются только совместимые величины. Проценты, ставки, простые количества и строки с ошибками исключаются. Подсказка перечисляет их, например «Пропущена строка 2 (people = 2)».
- Каждая сумма подсчитывается один раз, поэтому помеченная цена, которую позже умножает помеченная строка, учитывается в этой строке, а не в обеих.
Таким образом, заголовок - это все, что нужно, чтобы сохранить одну неделю #food отдельно от следующей:
# Week 1£20 lunch #food даёт £20.00total of #food даёт £20.00# Week 2£30 lunch #food даёт £30.00total of #food даёт £30.00Когда нечего добавить, строка говорит об этом, а не показывает пробел или ноль, что обычно означает опечатку в теге или заголовке, который вы забыли:
£12.50 lunch #food даёт £12.50total of #drinks даёт Unsupported: no lines tagged #drinks abovering the plumber #jobstotal of #jobs даёт Unsupported: no amounts tagged #jobs aboveЗапись имён тегов
Имя тега может содержать буквы, цифры, _, - и /, поэтому #q1-2026 и #trip/lisbon являются каждым именем. Заглавные буквы не имеют значения:
£20 flight #trip/lisbon даёт £20.00£35 hotel #Trip/Lisbon даёт £35.00total of #trip/lisbon даёт £55.00#, который не соединен со словом, сохраняет свой старый смысл, поэтому ничего из того, что вы уже написали, не меняется:
| Что вы пишете | Что это такое |
|---|---|
# Weekly shop |
Комментарий: после решётки стоит пробел |
5 + 5 # comment |
То же самое: всё после решётки игнорируется |
C#4 in Hz |
Музыкальный диез: решётка примыкает к обозначению ноты |
#1, Invoice #123 |
Число, а не тег: имя тега не может начинаться с цифры |
#ff0000, #fff |
Цветовой код |
varlig.app/docs#tags |
Веб-адрес с фрагментом |
Имя тега должно начинаться с буквы. Последовательность из трёх, четырёх, шести или восьми шестнадцатеричных цифр после решётки читается как цвет: поэтому #fee — цвет, а #fees — тег.
Теги в заметке и теги в блоке
Теги для организации заметок в боковой панели описаны в разделе Теги, ссылки и обратные ссылки. Они не распространяются внутрь блоков вычислений. Запись #food в блоке помечает строку для подсчёта и не появляется в боковой панели. Запись #food в обычном тексте организует заметку, не влияя на вычисления. Для обеих задач добавьте тег в обоих местах. Есть и различие в синтаксисе: тег заметки может содержать пробелы, если закрыть его вторым #, а тег в блоке вычислений заканчивается при первом пробеле.
Справочник функций списков
| Вызов | Действие |
|---|---|
range(start,end) |
Целые числа от start до end включительно |
range(start,end,step) |
Последовательность с шагом step; шаг может быть отрицательным или дробным, но не нулевым |
length(list), count(list) |
Количество значений |
sort(list) |
По возрастанию; только числа без единиц |
reverse(list) |
Те же значения в обратном порядке; допускаются любые значения |
unique(list) |
Оставить первое вхождение каждого значения |
slice(list,start,end) |
Значения от индекса start до, но не включая индекс end |
map(expression,variable,list) |
Вычислить выражение для каждого значения |
filter(condition,variable,list) |
Оставить значения, для которых условие равно true |
range(1, 5) даёт [1, 2, 3, 4, 5]range(0, 100, 25) даёт [0, 25, 50, 75, 100]range(10, 0, -2) даёт [10, 8, 6, 4, 2, 0]scores = [72, 85, 91, 64, 88]sort(scores) даёт [64, 72, 85, 88, 91]reverse(sort(scores)) даёт [91, 88, 85, 72, 64]slice(sort(scores), 0, 3) даёт [64, 72, 85]unique([4, 2, 4, 6, 2]) даёт [4, 2, 6]reverse(sort(…)) возвращает наибольшее сначала, а slice(sort(…), 0, 3) выбирает три самых низких.
Границы среза должны удовлетворять 0 <= start <= end <= length. Одинаковые start и end дают пустой список. Сокращение scores[0:2] не поддерживается; пишите slice(scores, 0, 2).
Функция unique сравнивает сохранённые значения точно. Поэтому 1 kg и 1000 g считаются разными, а результаты, различающиеся в десятом знаке после запятой, не объединяются.
Преобразование и фильтрация: map и filter
Функция map вычисляет выражение для каждого элемента списка. filter оставляет элементы, удовлетворяющие условию. В обоих случаях сначала идёт выражение, затем имя текущего элемента, затем список:
scores = [72, 85, 91, 64, 88]map(s + 5, s, scores) даёт [77, 90, 96, 69, 93]filter(s >= 80, s, scores) даёт [85, 91, 88]count(filter(s >= 80, s, scores)) даёт 3average(filter(s >= 80, s, scores)) даёт 88Прочитайте filter(s >= 80, s, scores) как "значения s в scores, где s >= 80". Оба работают с единицами и деньгами:
map(p * 1.2, p, [£10, £25, £40]) даёт [£12.00, £30.00, £48.00]spend = [£42.50, £18.20, £65.00, £23.30]filter(x > £30, x, spend) даёт [£42.50, £65.00]sum(filter(x > £30, x, spend)) даёт £107.50Выбранное вами имя существует только внутри вызова. Он не меняет значение того же имени в другом месте примечания:
x = 10map(x * 2, x, [1, 2, 3]) даёт [2, 4, 6]x даёт 10Условие в filter должно быть сравнением или другим логическим значением true/false. Обычное число не превращается в true, поэтому filter(x, x, [0, 1, 2]) вызывает ошибку. Применение map или filter к пустому списку возвращает пустой список.
Арифметика со списками
Вы можете умножить или разделить каждое значение на одно число, а также добавить или вычесть два списка одинаковой длины по значению:
[30, 36, 22] / 40 * 100 даёт [75, 90, 55]2 * [3, 1, 4] даёт [6, 2, 8]-[5, -3] даёт [-5, 3]mocks = [62, 70, 60]finals = [72, 78, 69]finals - mocks даёт [10, 8, 9]average(finals - mocks) даёт 9[1 kg, 2 kg] + [500 g, 500 g] даёт [1.5 kg, 2.5 kg][72, 85] == [72, 85] даёт trueПервая строка переводит баллы из 40 в проценты. Строка finals - mocks соединяет тестовый балл каждого студента с его финальным баллом.
Некоторые операции не поддерживаются в списках:
- Прибавление одного числа ко всему списку, как в
scores + 5. Вместо этого используйтеmap(s + 5, s, scores). - Сложение списков разной длины. Значения не повторяются автоматически для выравнивания размеров.
- Умножение двух плоских списков через
*. Для суммы попарных произведений используйтеdot:dot([2, 3, 1], [4, 5, 10])даёт33, например за два кофе по 4, три чая по 5 и один торт за 10. Для списков строк*выполняет матричное умножение; см. Векторы и матрицы.
Списки строк
Список строк работает как маленькая таблица. average и sum работают вниз по столбцам, а map может работать по строкам:
# Each row is one student: [mock, final]results = [[62, 72], [70, 78], [60, 69]]average(results) даёт [64, 73]sum(results) даёт [192, 219]map(average(r), r, results) даёт [67, 74, 64.5]median, min, max и stddev не принимают списки строк. Используйте map над строками, как в последней строке, или вытащите столбцы в отдельный список.
Точные правила для всех этих операций находятся в справке по продвинутой математике.
Всё вместе
Вот неделя подсчета шагов с часов, с ежедневной целью:
# Steps, Monday to Sundaysteps = [8200, 10400, 6300, 12000, 9100, 7400, 9600]goal = 9000sum(steps) даёт 63,000average(steps) даёт 9,000median(steps) даёт 9,100Days on target: count(filter(s >= goal, s, steps)) даёт 4Spread: max(steps) - min(steps) даёт 5,700# Roughly 0.75 m per stepwalked = sum(steps) * 0.75 mwalked in km даёт 47.25 kmСреднее точно совпало с целью, но достичь её удалось лишь в четыре дня. Разница между лучшим и худшим днями — 5700 шагов. Измените goal или вставьте данные следующей недели, и все строки обновятся.