A list is an ordered, mutable (changeable) collection. Lists can contain different data types like numbers, strings, or even other lists.
fruits = ["apple", "banana", "cherry"]π Why Use Lists?
To store multiple items in a single variable.
To maintain order (items have a specific index).
To easily add, remove, or modify items.
π§ Indexing & Slicing
print(fruits[1]) # 2nd item
print(fruits[-1]) # Last item
print(fruits[1:3]) # Slice from 2nd to 3rd itemπ Common List Operations
fruits.append("orange") # β Add to end
fruits.insert(1, "grape") # β Add at specific index
fruits.remove("banana") # β Remove item by value
print(fruits[0]) # π Access first element
print(len(fruits)) # π Get number of items
fruits.pop() # Removes last item
fruits.index("cherry") # Finds index of an item
fruits.sort() # Sorts the list
fruits.reverse() # Reverses the list orderπ Loop Through a List
for fruit in fruits:
print(fruit)apple
grape
cherry
orangeπ§ͺ Example: Mixing Data Types
random_stuff = [42, "hello", 3.14, True]Lists are flexible β you can store anything!
<div class="infographic-pylist">
<style>
.infographic-pylist {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--error: #c0392b;
--error-soft: #fbe9e7;
--mono-font: 'IBM Plex Mono', 'SFMono-Regular', Menlo, monospace;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', system-ui, sans-serif;
box-sizing: border-box;
max-width: 800px;
margin: 0 auto;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-pylist[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--error: #e57373;
--error-soft: #3a2222;
}
.infographic-pylist *, .infographic-pylist *::before, .infographic-pylist *::after { box-sizing: border-box; }
.infographic-pylist .pl-wrap { padding: 0 clamp(1rem, 4vw, 2rem) 1.5rem; }
.infographic-pylist h1 {
font-family: var(--display-font); font-weight: 600;
font-size: clamp(1.55rem, 5vw, 2.1rem); text-align: center; margin: 1.5rem 0 0.25rem; letter-spacing: -0.01em;
}
.infographic-pylist .pl-sub { text-align: center; color: var(--ink-soft); font-size: 0.88rem; margin: 0 0 1.4rem; }
.infographic-pylist .pl-tabs { display: flex; justify-content: center; gap: 0.4rem; margin-bottom: 1.5rem; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.infographic-pylist .pl-tab-btn {
font: inherit; font-family: var(--mono-font); font-size: 0.82rem; font-weight: 700;
background: none; border: none; border-bottom: 2.5px solid transparent; color: var(--ink-soft);
padding: 0.55rem 0.85rem; cursor: pointer; margin-bottom: -1px;
}
.infographic-pylist .pl-tab-btn.is-active { color: var(--accent); border-bottom-color: var(--accent); }
.infographic-pylist .pl-panel.is-hidden-tab { display: none; }
/* box visualization */
.infographic-pylist .box-row { display: flex; justify-content: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.6rem; min-height: 70px; align-items: flex-end; }
.infographic-pylist .box-col { display: flex; flex-direction: column; align-items: center; gap: 0.2rem; }
.infographic-pylist .box-idx { font-family: var(--mono-font); font-size: 0.65rem; color: var(--ink-soft); }
.infographic-pylist .box-idx.neg { color: var(--accent); }
.infographic-pylist .box {
min-width: 56px; padding: 0 0.5rem; height: 44px; display: flex; align-items: center; justify-content: center;
font-family: var(--mono-font); font-size: 0.82rem; font-weight: 700;
background: var(--paper-alt); border: 1.5px solid var(--line); border-radius: 6px; color: var(--ink);
transition: background 0.2s, border-color 0.2s, transform 0.2s; cursor: default;
animation: pl-pop-in 0.25s ease;
}
@keyframes pl-pop-in { from { opacity: 0; transform: scale(0.7); } to { opacity: 1; transform: scale(1); } }
.infographic-pylist .box.is-clickable { cursor: pointer; }
.infographic-pylist .box.is-highlight { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); transform: translateY(-3px); }
.infographic-pylist .box.type-str { border-color: #2563eb; }
.infographic-pylist .box.type-int { border-color: #1f9d55; }
.infographic-pylist .box.type-float { border-color: #b45309; }
.infographic-pylist .box.type-bool { border-color: #9333ea; }
.infographic-pylist .type-tag { font-size: 0.6rem; color: var(--ink-soft); font-family: var(--mono-font); }
.infographic-pylist .len-badge {
display: block; text-align: center; font-family: var(--mono-font); font-size: 0.75rem; color: var(--accent);
font-weight: 700; margin-bottom: 1.1rem;
}
/* method cards */
.infographic-pylist .method-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.6rem; margin-bottom: 1.1rem; }
@media (max-width: 560px) { .infographic-pylist .method-grid { grid-template-columns: 1fr; } }
.infographic-pylist .method-card { background: var(--paper-alt); border: 1px solid var(--line); border-radius: 6px; padding: 0.6rem 0.7rem; }
.infographic-pylist .method-name { font-family: var(--mono-font); font-size: 0.8rem; font-weight: 700; color: var(--ink); margin-bottom: 0.4rem; }
.infographic-pylist .method-row { display: flex; gap: 0.35rem; align-items: center; flex-wrap: wrap; }
.infographic-pylist .method-row input {
font-family: var(--mono-font); font-size: 0.78rem; padding: 0.28rem 0.4rem;
border: 1px solid var(--line); border-radius: 4px; background: var(--paper); color: var(--ink); width: 72px;
}
.infographic-pylist .method-row input:focus { outline: none; border-color: var(--accent); }
.infographic-pylist .run-btn {
font: inherit; font-family: var(--mono-font); font-size: 0.75rem; font-weight: 700;
background: var(--accent); color: #fff; border: none; border-radius: 4px;
padding: 0.3rem 0.6rem; cursor: pointer;
}
.infographic-pylist .run-btn:disabled { opacity: 0.5; cursor: default; }
.infographic-pylist .reset-row { display: flex; justify-content: center; margin-bottom: 1rem; }
.infographic-pylist .reset-btn {
font: inherit; font-size: 0.78rem; font-weight: 600; color: var(--ink-soft);
background: none; border: 1px solid var(--line); padding: 0.35rem 0.7rem; cursor: pointer; border-radius: 4px;
}
/* terminal log β always dark */
.infographic-pylist .device {
--ed-bg: #1e1e1e; --ed-bar: #2d2d2d; --ed-text: #d4d4d4; --ed-soft: #8a8a8a; --ed-ok: #6fdc8c; --ed-err: #ff6b6b;
background: var(--ed-bg); border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
}
.infographic-pylist .device-bar {
display: flex; align-items: center; gap: 0.4rem;
background: var(--ed-bar); padding: 0.5rem 0.7rem; border-bottom: 1px solid #3a3a3a;
font-size: 0.72rem; color: var(--ed-soft); font-weight: 600;
}
.infographic-pylist .device-bar .dot { width: 9px; height: 9px; border-radius: 50%; background: #5a5a5a; }
.infographic-pylist .device-bar .dot:nth-child(1) { background: #ff5f56; }
.infographic-pylist .device-body {
padding: 0.8rem 0.9rem; font-family: var(--mono-font); font-size: 0.78rem; color: var(--ed-text);
min-height: 50px; max-height: 170px; overflow-y: auto;
}
.infographic-pylist .log-line { display: flex; gap: 0.5rem; line-height: 1.6; opacity: 0; animation: pl-fadein 0.25s ease forwards; flex-wrap: wrap; }
@keyframes pl-fadein { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: translateY(0); } }
.infographic-pylist .log-line .p { color: var(--ed-ok); font-weight: 700; }
.infographic-pylist .log-line .arrow { color: var(--ed-soft); }
.infographic-pylist .log-line .res { color: #fff; }
.infographic-pylist .log-line.err .res { color: var(--ed-err); }
.infographic-pylist .log-empty { color: var(--ed-soft); }
/* indexing/slicing tab */
.infographic-pylist .idx-result {
text-align: center; font-family: var(--mono-font); font-size: 1rem; font-weight: 700; color: var(--accent);
margin: 0.8rem 0 1.2rem; min-height: 1.4em;
}
.infographic-pylist .slice-controls { display: flex; justify-content: center; align-items: center; gap: 1.2rem; margin-bottom: 0.6rem; }
.infographic-pylist .slice-slot { display: flex; flex-direction: column; align-items: center; gap: 0.3rem; }
.infographic-pylist .slice-slot span { font-family: var(--mono-font); font-size: 0.7rem; color: var(--ink-soft); }
.infographic-pylist .stepper { display: flex; align-items: center; gap: 0.4rem; }
.infographic-pylist .stepper button {
width: 28px; height: 28px; border-radius: 50%; border: 1.5px solid var(--line);
background: var(--paper-alt); color: var(--ink); font-size: 1rem; font-weight: 700; cursor: pointer;
}
.infographic-pylist .stepper .val { font-family: var(--display-font); font-size: 1.1rem; color: var(--accent); min-width: 1.6ch; text-align: center; }
.infographic-pylist .pl-caption { text-align: center; font-size: 0.8rem; color: var(--ink-soft); margin-top: 0.3rem; }
.infographic-pylist .idx-picker-row {
display: flex; justify-content: center; align-items: center; gap: 0.35rem; margin-top: 0.9rem;
font-family: var(--mono-font); font-size: 0.95rem; color: var(--ink-soft);
}
.infographic-pylist .idx-picker-input {
width: 60px; font-family: var(--mono-font); font-size: 0.95rem; font-weight: 700; text-align: center;
padding: 0.3rem 0.3rem; border: 1.5px solid var(--line); border-radius: 5px; background: var(--paper-alt); color: var(--accent);
}
.infographic-pylist .idx-picker-input:focus { outline: none; border-color: var(--accent); }
@media (prefers-reduced-motion: reduce) {
.infographic-pylist *, .infographic-pylist *::before, .infographic-pylist *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="pl-wrap">
<h1>Python Lists</h1>
<p class="pl-sub">One list. Tap methods, indices, or slices to see it move.</p>
<div class="pl-tabs">
<button class="pl-tab-btn is-active" data-tab="ops">Operations</button>
<button class="pl-tab-btn" data-tab="idx">Indexing & Slicing</button>
</div>
<!-- OPERATIONS TAB -->
<div class="pl-panel" id="tabOps">
<div class="box-row" id="opsBoxRow"></div>
<span class="len-badge" id="opsLenBadge">len(fruits) = 3</span>
<div class="method-grid">
<div class="method-card">
<div class="method-name">.append(x)</div>
<div class="method-row">
<input id="appendInput" type="text" value="orange" />
<button class="run-btn" data-method="append">Run</button>
</div>
</div>
<div class="method-card">
<div class="method-name">.insert(i, x)</div>
<div class="method-row">
<input id="insertIdx" type="text" value="1" style="width:44px" />
<input id="insertVal" type="text" value="grape" />
<button class="run-btn" data-method="insert">Run</button>
</div>
</div>
<div class="method-card">
<div class="method-name">.remove(x)</div>
<div class="method-row">
<input id="removeInput" type="text" value="banana" />
<button class="run-btn" data-method="remove">Run</button>
</div>
</div>
<div class="method-card">
<div class="method-name">.index(x)</div>
<div class="method-row">
<input id="indexInput" type="text" value="cherry" />
<button class="run-btn" data-method="index">Run</button>
</div>
</div>
<div class="method-card">
<div class="method-name">.pop()</div>
<div class="method-row"><button class="run-btn" data-method="pop">Run</button></div>
</div>
<div class="method-card">
<div class="method-name">.sort()</div>
<div class="method-row"><button class="run-btn" data-method="sort">Run</button></div>
</div>
<div class="method-card">
<div class="method-name">.reverse()</div>
<div class="method-row"><button class="run-btn" data-method="reverse">Run</button></div>
</div>
<div class="method-card">
<div class="method-name">len(fruits)</div>
<div class="method-row"><button class="run-btn" data-method="len">Run</button></div>
</div>
</div>
<div class="reset-row"><button class="reset-btn" id="opsReset">βΊ Reset list</button></div>
<div class="device">
<div class="device-bar"><span class="dot"></span><span class="dot"></span><span class="dot"></span> History</div>
<div class="device-body" id="opsLog"><div class="log-empty">Run a method to see it hereβ¦</div></div>
</div>
</div>
<!-- INDEXING/SLICING TAB -->
<div class="pl-panel is-hidden-tab" id="tabIdx">
<div class="box-row" id="idxBoxRowPos"></div>
<div class="box-row" id="idxBoxRowNeg" style="margin-top:-0.4rem;"></div>
<span class="len-badge" id="idxLenBadge">len(fruits) = 3</span>
<p class="pl-caption">Tap a box (or its index) β positive above, negative below.</p>
<div class="idx-picker-row">
<span>fruits[</span>
<input class="idx-picker-input" id="idxPickerInput" type="text" value="0" inputmode="numeric" />
<span>]</span>
</div>
<div class="idx-result" id="idxSingleResult">fruits[0] = "apple"</div>
<p class="pl-caption">Negative index? Python counts backward from the end: -1 is the last item.</p>
<div class="slice-controls">
<div class="slice-slot">
<span>start</span>
<div class="stepper">
<button id="sliceStartMinus">β</button>
<span class="val" id="sliceStartVal">0</span>
<button id="sliceStartPlus">+</button>
</div>
</div>
<div class="slice-slot">
<span>end</span>
<div class="stepper">
<button id="sliceEndMinus">β</button>
<span class="val" id="sliceEndVal">2</span>
<button id="sliceEndPlus">+</button>
</div>
</div>
</div>
<div class="idx-result" id="sliceResult">fruits[0:2]</div>
<p class="pl-caption">Start/end can go negative too β the slice includes start, stops before end.</p>
</div>
</div>
<script>
(function () {
var root = document.currentScript.closest('.infographic-pylist')
|| document.querySelector('.infographic-pylist');
var bodyAttr = document.body.getAttribute('data-darkmode');
var dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
var match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) root.setAttribute('data-theme', 'dark');
/* ---------------- tabs ---------------- */
var tabBtns = root.querySelectorAll('.pl-tab-btn');
var panels = {
ops: root.querySelector('#tabOps'),
idx: root.querySelector('#tabIdx')
};
tabBtns.forEach(function (btn) {
btn.addEventListener('click', function () {
tabBtns.forEach(function (b) { b.classList.toggle('is-active', b === btn); });
var target = btn.dataset.tab;
Object.keys(panels).forEach(function (key) {
panels[key].classList.toggle('is-hidden-tab', key !== target);
});
if (target === 'idx') renderIdxTab();
});
});
/* ---------------- shared list state ---------------- */
var INITIAL = ['apple', 'banana', 'cherry'];
var fruits = INITIAL.slice();
function pyRepr(arr) {
return '[' + arr.map(function (v) { return "'" + v + "'"; }).join(', ') + ']';
}
/* ---------------- render helpers ---------------- */
function renderBoxRow(container, arr, opts) {
opts = opts || {};
container.innerHTML = '';
arr.forEach(function (val, i) {
var col = document.createElement('div');
col.className = 'box-col';
if (opts.showPosIdx) {
var idxLbl = document.createElement('span');
idxLbl.className = 'box-idx';
idxLbl.textContent = i;
col.appendChild(idxLbl);
}
var box = document.createElement(opts.clickable ? 'button' : 'div');
box.className = 'box' + (opts.clickable ? ' is-clickable' : '');
if (opts.highlightSet && opts.highlightSet.has(i)) box.classList.add('is-highlight');
if (opts.typeClass) box.classList.add('type-' + opts.typeClass(val));
box.textContent = opts.display ? opts.display(val) : val;
if (opts.onClick) box.addEventListener('click', function () { opts.onClick(i); });
col.appendChild(box);
if (opts.showNegIdx) {
var negLbl = document.createElement('span');
negLbl.className = 'box-idx neg';
negLbl.textContent = i - arr.length;
col.appendChild(negLbl);
}
container.appendChild(col);
});
}
/* ---------------- OPERATIONS TAB ---------------- */
var opsBoxRow = root.querySelector('#opsBoxRow');
var opsLenBadge = root.querySelector('#opsLenBadge');
var opsLog = root.querySelector('#opsLog');
var opsFirstLog = true;
function renderOps() {
renderBoxRow(opsBoxRow, fruits, {});
opsLenBadge.textContent = 'len(fruits) = ' + fruits.length;
}
function logLine(code, result, isErr) {
if (opsFirstLog) { opsLog.innerHTML = ''; opsFirstLog = false; }
var line = document.createElement('div');
line.className = 'log-line' + (isErr ? ' err' : '');
line.innerHTML = '<span class="p">>>></span><span>' + code + '</span>' +
(result !== undefined ? '<span class="arrow">β</span><span class="res">' + result + '</span>' : '');
opsLog.appendChild(line);
opsLog.scrollTop = opsLog.scrollHeight;
}
function runMethod(method) {
if (method === 'append') {
var v = root.querySelector('#appendInput').value.trim() || 'item';
fruits.push(v);
logLine('fruits.append("' + v + '")', pyRepr(fruits));
} else if (method === 'insert') {
var i = parseInt(root.querySelector('#insertIdx').value, 10);
var v2 = root.querySelector('#insertVal').value.trim() || 'item';
if (isNaN(i)) { logLine('fruits.insert(...)', 'invalid index', true); renderOps(); return; }
i = Math.max(0, Math.min(fruits.length, i));
fruits.splice(i, 0, v2);
logLine('fruits.insert(' + i + ', "' + v2 + '")', pyRepr(fruits));
} else if (method === 'remove') {
var v3 = root.querySelector('#removeInput').value.trim();
var pos = fruits.indexOf(v3);
if (pos === -1) {
logLine('fruits.remove("' + v3 + '")', 'ValueError: not in list', true);
} else {
fruits.splice(pos, 1);
logLine('fruits.remove("' + v3 + '")', pyRepr(fruits));
}
} else if (method === 'index') {
var v4 = root.querySelector('#indexInput').value.trim();
var pos2 = fruits.indexOf(v4);
if (pos2 === -1) {
logLine('fruits.index("' + v4 + '")', 'ValueError: not in list', true);
} else {
logLine('fruits.index("' + v4 + '")', pos2);
}
} else if (method === 'pop') {
if (fruits.length === 0) {
logLine('fruits.pop()', 'IndexError: pop from empty list', true);
} else {
var popped = fruits.pop();
logLine('fruits.pop()', "'" + popped + "' (list now " + pyRepr(fruits) + ')');
}
} else if (method === 'sort') {
fruits.sort();
logLine('fruits.sort()', pyRepr(fruits));
} else if (method === 'reverse') {
fruits.reverse();
logLine('fruits.reverse()', pyRepr(fruits));
} else if (method === 'len') {
logLine('len(fruits)', fruits.length);
}
renderOps();
}
root.querySelectorAll('#tabOps .run-btn').forEach(function (btn) {
btn.addEventListener('click', function () { runMethod(btn.dataset.method); });
});
root.querySelector('#opsReset').addEventListener('click', function () {
fruits = INITIAL.slice();
opsFirstLog = true;
opsLog.innerHTML = '<div class="log-empty">Run a method to see it hereβ¦</div>';
sliceStart = 0;
sliceEnd = 2;
idxPickerInput.value = '0';
renderOps();
renderIdxTab();
});
/* ---------------- INDEXING / SLICING TAB ---------------- */
var idxBoxRowPos = root.querySelector('#idxBoxRowPos');
var idxBoxRowNeg = root.querySelector('#idxBoxRowNeg');
var idxLenBadge = root.querySelector('#idxLenBadge');
var idxPickerInput = root.querySelector('#idxPickerInput');
var idxSingleResult = root.querySelector('#idxSingleResult');
var sliceResult = root.querySelector('#sliceResult');
var sliceStartVal = root.querySelector('#sliceStartVal');
var sliceEndVal = root.querySelector('#sliceEndVal');
var sliceStart = 0;
var sliceEnd = 2;
function clamp(v, lo, hi) { return Math.max(lo, Math.min(hi, v)); }
function resolveIndex(raw) {
var n = fruits.length;
if (isNaN(raw)) return { ok: false, msg: 'enter a whole number' };
if (raw < -n || raw >= n) return { ok: false, msg: 'IndexError: list index out of range', pos: null };
var pos = raw < 0 ? raw + n : raw;
return { ok: true, pos: pos, value: fruits[pos] };
}
function renderIdxTab() {
sliceStart = clamp(sliceStart, -fruits.length, fruits.length);
sliceEnd = clamp(sliceEnd, -fruits.length, fruits.length);
var rawIdx = parseInt(idxPickerInput.value, 10);
var resolved = resolveIndex(rawIdx);
var hl = new Set();
var normStart = sliceStart < 0 ? sliceStart + fruits.length : sliceStart;
var normEnd = sliceEnd < 0 ? sliceEnd + fruits.length : sliceEnd;
for (var k = Math.max(0, normStart); k < Math.min(fruits.length, normEnd); k++) hl.add(k);
if (resolved.ok) hl.add(resolved.pos);
renderBoxRow(idxBoxRowPos, fruits, {
showPosIdx: true,
clickable: true,
highlightSet: hl,
onClick: function (i) {
idxPickerInput.value = i;
renderIdxTab();
}
});
idxBoxRowNeg.innerHTML = '';
fruits.forEach(function (v, i) {
var col = document.createElement('div');
col.className = 'box-col';
var lbl = document.createElement('button');
lbl.className = 'box-idx neg';
lbl.style.cssText = 'background:none;border:none;cursor:pointer;font-family:inherit;font-size:inherit;padding:0;';
lbl.textContent = i - fruits.length;
lbl.addEventListener('click', function () {
idxPickerInput.value = i - fruits.length;
renderIdxTab();
});
col.appendChild(lbl);
idxBoxRowNeg.appendChild(col);
});
idxLenBadge.textContent = 'len(fruits) = ' + fruits.length;
idxSingleResult.textContent = resolved.ok
? ('fruits[' + rawIdx + '] = "' + resolved.value + '"')
: (isNaN(rawIdx) ? 'Enter a whole number.' : resolved.msg);
sliceStartVal.textContent = sliceStart;
sliceEndVal.textContent = sliceEnd;
var sliceArr = fruits.slice(normStart, normEnd);
sliceResult.textContent = 'fruits[' + sliceStart + ':' + sliceEnd + '] = ' + pyRepr(sliceArr);
}
idxPickerInput.addEventListener('input', renderIdxTab);
root.querySelector('#sliceStartMinus').addEventListener('click', function () { sliceStart = clamp(sliceStart - 1, -fruits.length, fruits.length); renderIdxTab(); });
root.querySelector('#sliceStartPlus').addEventListener('click', function () { sliceStart = clamp(sliceStart + 1, -fruits.length, fruits.length); renderIdxTab(); });
root.querySelector('#sliceEndMinus').addEventListener('click', function () { sliceEnd = clamp(sliceEnd - 1, -fruits.length, fruits.length); renderIdxTab(); });
root.querySelector('#sliceEndPlus').addEventListener('click', function () { sliceEnd = clamp(sliceEnd + 1, -fruits.length, fruits.length); renderIdxTab(); });
renderOps();
renderIdxTab();
})();
</script>
</div>β Summary
Feature | Description |
|---|---|
Mutable | You can change it after creation |
Indexed | Items have positions (0, 1, 2β¦) |
Versatile | Can hold any data types |
Dynamic | Grows/shrinks as needed |