Zum Inhalt springen
Varlig-Handbuch
Varlig-Startseite

Listen und Statistik

Eine Liste hält mehrere Werte unter einem Namen zusammen, etwa die Schrittzahlen einer Woche, eine Reihe von Klausurpunkten oder die Kassenbons eines Monats. Stehen die Werte erst in einer Liste, kannst du sie summieren, ihren Durchschnitt bilden, messen, wie stark sie streuen, und die wichtigen herausgreifen.

Auf dieser Seite geht es darum, Listen zu schreiben und zu indizieren, um Kennzahlen, Sortieren und Ausschneiden, um das Umformen einer Liste mit map und filter und um Rechnen mit ganzen Listen. Sie hilft dir immer dann, wenn du eine Spalte voller Zahlen zusammenfassen willst. Listen aus Zeilen können auch als Matrizen dienen, die eine eigene Seite haben.

Eine Liste schreiben

Schreib die Werte in eckige Klammern, getrennt durch Kommas:

calc
Punkte = [72, 85, 91, 64, 88] ergibt [72, 85, 91, 64, 88]
Punkte[0] ergibt 72
Punkte[4] ergibt 88
length(Punkte) ergibt 5

Die Position eines Werts in der Liste ist sein Index, den du in eckigen Klammern hinter die Liste schreibst. Indizes beginnen bei null, Punkte[0] ist also das erste Ergebnis und Punkte[4] das fünfte. Das letzte Element steht immer bei length(Punkte) - 1. Ein negativer, gebrochener oder zu großer Index ist ein Fehler; Indizes zählen nicht vom Ende her weiter.

Elemente können Rechnungen, Größen mit Einheiten oder andere Listen sein:

calc
[2 * 45, 60 + 15] ergibt [90, 75]
[1.5 kg, 750 g] ergibt [1.5 kg, 750 g]
[[1, 2], [3, 4]][1][0] ergibt 3

Bei verschachtelten Listen wählt der erste Index die innere Liste und der zweite einen Wert daraus: [1] wählt [3, 4], dann wählt [0] die 3.

Tausendertrennzeichen funktionieren auch innerhalb einer Liste, du kannst Zahlen also so einsetzen, wie sie geschrieben sind. Setz nach jedem Komma zwischen zwei Werten ein Leerzeichen; ein Komma, auf das drei Ziffern folgen, bleibt Teil der Zahl:

calc
Gehälter = [£32,000, £41,500, £38,250] ergibt [£32,000.00, £41,500.00, £38,250.00]
average(Gehälter) ergibt £37,250.00

Worauf du achten solltest:

  • Ohne Leerzeichen trennt jedes Komma, [8200,10400] hat also zwei Werte. Eine Liste wie [100,200,300] kann eine Zahl oder drei sein, deshalb zeigt Varlig einen Fehler an, der beide Schreibweisen nennt.
  • Ergebnisse zeigen Tausendertrennzeichen und nach jedem Komma ein Leerzeichen, [8,200, 10,400] ist also eine Liste mit zwei Werten.
  • Eine Liste enthält höchstens 1.024 Werte.

Kennzahlen

calc
Punkte = [72, 85, 91, 64, 88]
sum(Punkte) ergibt 400
average(Punkte) ergibt 80
median(Punkte) ergibt 85
min(Punkte) ergibt 64
max(Punkte) ergibt 91
count(Punkte) ergibt 5

mean und avg sind andere Namen für average, total für sum, stdev für stddev und count für length, Gewohnheiten aus Tabellenkalkulationen funktionieren also weiter. product multipliziert die Werte miteinander. Eine Perzentilfunktion gibt es nicht; median liefert den mittleren Wert.

Bei einer benannten Liste kannst du die Kennzahl auch in Worten schreiben:

calc
Punkte = [72, 85, 91, 64, 88]
average of Punkte ergibt 80
total of Punkte ergibt 400

sum of, mean of, median of, min of, max of und count of funktionieren genauso. Schreib nach of einen Namen oder die Werte selbst, getrennt durch Kommas, mit oder ohne runde Klammern. Für Werte in eckigen Klammern nimm die Funktionsschreibweise, wie in average([72, 85, 91]).

Die meisten Kennzahlen, darunter sum, product, average, median, min, max, count und stddev, akzeptieren statt einer Liste auch einzelne Werte:

calc
max(72, 85, 91) ergibt 91
average of 70, 85, 91 ergibt 82
mean of (1,2,3) ergibt 2
average(1,200, 1,800) ergibt 1,500

Die Zeilen darüber addieren

Eine Zeile, in der nur sum oder total steht, addiert die Ergebnisse darüber, zurück bis zur vorherigen sum- oder total-Zeile oder bis zu einer Trennlinie ---. Das funktioniert wie die Option Subtotal im Kontextmenü einer Zeile, so bekommt jeder Abschnitt einer Notiz schon beim Tippen seine eigene Summe:

calc
# Lebensmittel
Brot = £1.20
Milch = £1.45
Eier = £2.30
total ergibt £4.95
# Haushalt
Müllbeutel = £3.50
Spülmittel = £1.80
total ergibt £5.30

Hast du einem Wert den Namen sum oder total gegeben, zeigt die Zeile stattdessen deinen Wert.

Streuung: Varianz und Standardabweichung

calc
Punkte = [72, 85, 91, 64, 88]
variance(Punkte) ergibt 132.5
stddev(Punkte) to 1 dp ergibt 11.5

Beides sind Stichproben-Kennzahlen: Sie teilen durch die Anzahl der Werte minus eins (n - 1), die übliche Wahl, wenn deine Zahlen eine Stichprobe aus etwas Größerem sind. Sie brauchen mindestens zwei Werte. Hänge to 1 dp an eine beliebige Kennzahl an, um sie zu runden.

Ist deine Liste die gesamte Grundgesamtheit, willst du stattdessen durch n teilen. Bau das mit map nach, das weiter unten beschrieben ist:

calc
# Zugverspätungen in Minuten
Verspätungen = [2, 4, 4, 4, 5, 5, 7, 9]
stddev(Verspätungen) ergibt 2.1380899353
Mitte = average(Verspätungen) ergibt 5
sqrt(sum(map((x - Mitte)^2, x, Verspätungen)) / count(Verspätungen)) ergibt 2

Listen mit Einheiten

sum, average, median, min, max und stddev behalten Einheiten bei und rechnen zwischen kompatiblen Einheiten um:

calc
Arbeitswege = [24 min, 31 min, 27 min, 22 min]
sum(Arbeitswege) ergibt 104 min
average(Arbeitswege) ergibt 26 min
median(Arbeitswege) ergibt 25.5 min
sum([1 kg, 500 g]) ergibt 1.5 kg

variance akzeptiert nur reine Zahlen, weil das Ergebnis sonst in quadrierten Einheiten wäre. Auch sort funktioniert nur mit reinen Zahlen. Eine Kennzahl über Werte mit inkompatiblen Einheiten, etwa sum([1 kg, 3 m]), führt zu einem Fehler, statt stillschweigend Werte auszulassen.

Leere Listen

Aufruf mit einer leeren Liste Ergebnis
sum([]) 0
product([]) 1
count([]), length([]) 0
average([]), median([]), min([]), max([]) Fehler
variance([]), stddev([]) Fehler

Eine leere Liste entsteht meistens durch ein filter, auf das nichts zutraf, deshalb kann ein average über eine gefilterte Liste fehlschlagen, auch wenn die ursprüngliche Liste Werte enthält.

Listenreferenz

Aufruf Was er macht
range(Start,Ende) Ganze Zahlen von Start bis Ende, beide Enden eingeschlossen
range(Start,Ende,Schritt) Zählt in Schritten von Schritt, auch negativ oder gebrochen, aber nicht null
length(Liste), count(Liste) Anzahl der Werte
sort(Liste) Vom kleinsten zum größten Wert; nur reine Zahlen
reverse(Liste) Dieselben Werte in umgekehrter Reihenfolge; beliebige Werte
unique(Liste) Behält das erste Vorkommen jedes Werts
slice(Liste,Start,Ende) Werte ab Index Start bis ausschließlich Index Ende
map(Ausdruck,Variable,Liste) Berechnet den Ausdruck einmal für jeden Wert
filter(Bedingung,Variable,Liste) Behält die Werte, für die die Bedingung true ist
calc
range(1, 5) ergibt [1, 2, 3, 4, 5]
range(0, 100, 25) ergibt [0, 25, 50, 75, 100]
range(10, 0, -2) ergibt [10, 8, 6, 4, 2, 0]
Punkte = [72, 85, 91, 64, 88]
sort(Punkte) ergibt [64, 72, 85, 88, 91]
reverse(sort(Punkte)) ergibt [91, 88, 85, 72, 64]
slice(sort(Punkte), 0, 3) ergibt [64, 72, 85]
unique([4, 2, 4, 6, 2]) ergibt [4, 2, 6]

reverse(sort(…)) liefert den größten Wert zuerst, und slice(sort(…), 0, 3) greift die drei niedrigsten heraus.

Für die Grenzen von slice muss 0 <= Start <= Ende <= Länge gelten. Sind Start und Ende gleich, entsteht eine leere Liste. Eine Kurzform wie Punkte[0:2] gibt es nicht; schreib slice(Punkte, 0, 2).

unique vergleicht Werte genau so, wie sie gespeichert sind, 1 kg und 1000 g zählen also als zwei verschiedene Werte, und zwei Ergebnisse, die sich in der zehnten Nachkommastelle unterscheiden, werden nicht zusammengefasst.

Map und filter

map berechnet einen Ausdruck für jeden Wert einer Liste. filter behält die Werte, die eine Prüfung bestehen. In beiden Fällen kommt zuerst der Ausdruck, dann ein Name, der für jeden einzelnen Wert steht, dann die Liste:

calc
Punkte = [72, 85, 91, 64, 88]
map(s + 5, s, Punkte) ergibt [77, 90, 96, 69, 93]
filter(s >= 80, s, Punkte) ergibt [85, 91, 88]
count(filter(s >= 80, s, Punkte)) ergibt 3
average(filter(s >= 80, s, Punkte)) ergibt 88

Lies filter(s >= 80, s, Punkte) als „die Werte s in Punkte, für die s >= 80 gilt“. Beide funktionieren mit Einheiten und Geld:

calc
map(p * 1.2, p, [£10, £25, £40]) ergibt [£12.00, £30.00, £48.00]
Ausgaben = [£42.50, £18.20, £65.00, £23.30]
filter(x > £30, x, Ausgaben) ergibt [£42.50, £65.00]
sum(filter(x > £30, x, Ausgaben)) ergibt £107.50

Der gewählte Name existiert nur innerhalb des Aufrufs. Er ändert keinen gleichnamigen Wert an anderer Stelle der Notiz:

calc
x = 10
map(x * 2, x, [1, 2, 3]) ergibt [2, 4, 6]
x ergibt 10

Die Bedingung in filter muss ein Vergleich oder ein anderer Wahrheitswert sein. Eine reine Zahl gilt nicht als wahr, filter(x, x, [0, 1, 2]) ist also ein Fehler. Eine leere Liste mit map oder filter zu bearbeiten ergibt eine leere Liste.

Rechnen mit Listen

Du kannst jeden Wert mit einer einzelnen Zahl multiplizieren oder durch sie teilen und zwei gleich lange Listen Wert für Wert addieren oder subtrahieren:

calc
[30, 36, 22] / 40 * 100 ergibt [75, 90, 55]
2 * [3, 1, 4] ergibt [6, 2, 8]
-[5, -3] ergibt [-5, 3]
Probeklausur = [62, 70, 60]
Klausur = [72, 78, 69]
Klausur - Probeklausur ergibt [10, 8, 9]
average(Klausur - Probeklausur) ergibt 9
[1 kg, 2 kg] + [500 g, 500 g] ergibt [1.5 kg, 2.5 kg]
[72, 85] == [72, 85] ergibt true

Die erste Zeile macht aus Punkten von maximal 40 Prozentwerte. Die Zeile Klausur - Probeklausur stellt das Ergebnis der Probeklausur jeder Person ihrem Klausurergebnis gegenüber.

Einige Operationen werden bei Listen nicht unterstützt:

  • Eine einzelne Zahl zu einer Liste addieren, wie in Punkte + 5. Nimm stattdessen map(s + 5, s, Punkte).
  • Listen unterschiedlicher Länge addieren. Werte werden nie wiederholt, um die Längen anzugleichen.
  • Zwei flache Listen mit * multiplizieren. Für die Summe der paarweisen Produkte nimm dot: dot([2, 3, 1], [4, 5, 10]) ist 33, etwa zwei Kaffee zu je 4, drei Tee zu je 5 und ein Stück Kuchen zu 10. Zwischen Listen aus Zeilen ist * die Matrixmultiplikation, die unter Vektoren und Matrizen erklärt wird.

Listen aus Zeilen

Eine Liste aus Zeilen funktioniert wie eine kleine Tabelle. average und sum rechnen die Spalten hinunter, und map kann über die Zeilen hinweg rechnen:

calc
# Jede Zeile ist eine Person: [Probeklausur, Klausur]
Ergebnisse = [[62, 72], [70, 78], [60, 69]]
average(Ergebnisse) ergibt [64, 73]
sum(Ergebnisse) ergibt [192, 219]
map(average(r), r, Ergebnisse) ergibt [67, 74, 64.5]

median, min, max und stddev akzeptieren keine Listen aus Zeilen. Nimm map über die Zeilen, wie in der letzten Zeile, oder zieh eine Spalte in eine eigene Liste heraus.

Die genauen Regeln für all diese Operationen stehen in der Referenz Höhere Mathematik: Möglichkeiten und Grenzen.

Alles zusammen

Hier ist eine Woche voller Schrittzahlen von einer Uhr, mit einem Tagesziel:

calc
# Schritte, Montag bis Sonntag
Schritte = [8200, 10400, 6300, 12000, 9100, 7400, 9600]
Ziel = 9000
sum(Schritte) ergibt 63,000
average(Schritte) ergibt 9,000
median(Schritte) ergibt 9,100
Tage mit erreichtem Ziel: count(filter(s >= Ziel, s, Schritte)) ergibt 4
Spanne: max(Schritte) - min(Schritte) ergibt 5,700
# Etwa 0,75 m pro Schritt
Strecke = sum(Schritte) * 0.75 m
Strecke in km ergibt 47.25 km

Der Durchschnitt liegt genau auf dem Ziel, erreicht wurde es aber nur an vier Tagen, und zwischen dem besten und dem schlechtesten Tag liegen 5.700 Schritte. Ändere Ziel oder füge die Zahlen der nächsten Woche ein, und jede Zeile aktualisiert sich.