✅ enumerate()
💬 What it does:
Adds a counter (index) to each item in a list or any iterable.
names = ["Alice", "Bob", "Charlie"]
for index, name in enumerate(names):
print(index, name)0 Alice
1 Bob
2 Charlie💡 Why use it?
Instead of writing:
for i in range(len(names)):
print(i, names[i])You can use enumerate() to make it cleaner and more readable.
🧰 itertools — Powerful Tools for Iteration
The itertools module provides fast, memory-efficient tools for looping, especially when dealing with combinations, infinite sequences, or repeated patterns.
✅ count(start, step)
Keeps counting forever, starting from start, with a gap of step.
import itertools
for i in itertools.count(10, 2): # 10, 12, 14...
if i > 20:
break
print(i)10
12
14
16
18
20🧠 Use case: Generating invoice numbers, timestamps, etc.
✅ cycle(iterable)
Loops through the values endlessly.
for i, value in enumerate(itertools.cycle(["A", "B", "C"])):
if i == 6:
break
print(value)A
B
C
A
B
C🧠 Use case: Rotating banners, music playlists.
✅ repeat(elem, times)
Repeats a value multiple times.
for x in itertools.repeat("Hello", 3):
print(x)Hello
Hello
Hello🧠 Use case: Placeholder values, mocking data.
✅ chain()
Combines multiple iterables into one.
from itertools import chain
print(list(chain([1, 2], [3, 4]))) # [1, 2, 3, 4]🧠 Use case: Merging multiple data lists.
✅ combinations() and permutations()
from itertools import combinations, permutations
items = ["a", "b", "c"]
print(list(combinations(items, 2))) # No repetition, no reverse
print(list(permutations(items, 2))) # All orderings[('a', 'b'), ('a', 'c'), ('b', 'c')] # combinations
[('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'c'), ('c', 'a'), ('c', 'b')] # permutations🧠 Use case:
Combinations: Forming teams or pairs
Permutations: Shuffling passwords, game possibilities
<div class="infographic-pyitertools">
<style>
.infographic-pyitertools {
--ink:#1a1a1a; --ink-soft:#5c5c5c; --paper:#fff; --paper-alt:#f0ece4;
--accent:#2563eb; --accent-soft:#e3ebfd; --line:#ddd6c9;
--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:740px; margin:0 auto; font-family:var(--body-font); color:var(--ink); background:var(--paper);
}
.infographic-pyitertools[data-theme="dark"] {
--ink:#e8e6e1; --ink-soft:#9a968c; --paper:#121212; --paper-alt:#1e1e26;
--accent:#5b8def; --accent-soft:#202942; --line:#2c313d;
}
.infographic-pyitertools *,.infographic-pyitertools *::before,.infographic-pyitertools *::after{box-sizing:border-box;}
.infographic-pyitertools .it-wrap{padding:0 clamp(1rem,4vw,2rem) 1.5rem;}
.infographic-pyitertools h1{font-family:var(--display-font);font-weight:600;font-size:clamp(1.4rem,5vw,1.9rem);text-align:center;margin:1.5rem 0 0.25rem;letter-spacing:-0.01em;}
.infographic-pyitertools .it-sub{text-align:center;color:var(--ink-soft);font-size:0.85rem;margin:0 0 1.3rem;}
.infographic-pyitertools .it-tabs{display:flex;justify-content:center;gap:0.3rem;margin-bottom:1.4rem;border-bottom:1px solid var(--line);flex-wrap:wrap;}
.infographic-pyitertools .it-tab-btn{font:inherit;font-family:var(--mono-font);font-size:0.74rem;font-weight:700;background:none;border:none;border-bottom:2.5px solid transparent;color:var(--ink-soft);padding:0.5rem 0.6rem;cursor:pointer;margin-bottom:-1px;}
.infographic-pyitertools .it-tab-btn.is-active{color:var(--accent);border-bottom-color:var(--accent);}
.infographic-pyitertools .it-panel.is-hidden-tab{display:none;}
.infographic-pyitertools .code-line{text-align:center;font-family:var(--mono-font);font-size:0.78rem;color:var(--ink-soft);margin-bottom:1rem;}
.infographic-pyitertools .code-line strong{color:var(--accent);}
.infographic-pyitertools .row{display:flex;justify-content:center;gap:0.5rem;margin-bottom:0.8rem;flex-wrap:wrap;align-items:center;}
.infographic-pyitertools .row span{font-family:var(--mono-font);font-size:0.8rem;color:var(--ink-soft);}
.infographic-pyitertools .row input{font-family:var(--mono-font);font-size:0.82rem;padding:0.4rem 0.55rem;border:1.5px solid var(--line);border-radius:5px;background:var(--paper-alt);color:var(--ink);width:90px;text-align:center;}
.infographic-pyitertools .row input.wide{width:220px;}
.infographic-pyitertools .row input:focus{outline:none;border-color:var(--accent);}
.infographic-pyitertools .toggle-btn{font:inherit;font-family:var(--mono-font);font-size:0.78rem;font-weight:700;background:var(--paper-alt);border:1.5px solid var(--line);color:var(--ink-soft);padding:0.4rem 0.7rem;cursor:pointer;border-radius:6px;}
.infographic-pyitertools .toggle-btn.is-selected{border-color:var(--accent);color:var(--accent);background:var(--accent-soft);}
.infographic-pyitertools .btn{font:inherit;font-family:var(--mono-font);font-size:0.82rem;font-weight:700;background:var(--accent);color:#fff;border:none;border-radius:999px;padding:0.48rem 1rem;cursor:pointer;}
.infographic-pyitertools .btn:disabled{opacity:0.5;cursor:default;}
.infographic-pyitertools .chip-row{display:flex;flex-wrap:wrap;justify-content:center;gap:0.4rem;margin-bottom:0.9rem;min-height:40px;align-items:center;}
.infographic-pyitertools .chip{font-family:var(--mono-font);font-size:0.78rem;font-weight:700;padding:0.35rem 0.6rem;border-radius:6px;border:1.5px solid var(--line);background:var(--paper-alt);color:var(--ink);animation:it-pop .25s ease;}
@keyframes it-pop{from{opacity:0;transform:scale(.7);}to{opacity:1;transform:scale(1);}}
.infographic-pyitertools .chip.out{border-color:var(--accent);background:var(--accent-soft);color:var(--accent);}
.infographic-pyitertools .chip.idx{font-size:0.65rem;color:var(--ink-soft);font-weight:400;padding:0.2rem 0.4rem;background:none;border:none;}
.infographic-pyitertools .device{--ed-bg:#1e1e1e;--ed-bar:#2d2d2d;--ed-text:#d4d4d4;--ed-soft:#8a8a8a;--ed-ok:#6fdc8c;background:var(--ed-bg);border:1px solid var(--line);border-radius:8px;overflow:hidden;}
.infographic-pyitertools .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-pyitertools .device-bar .dot{width:9px;height:9px;border-radius:50%;background:#5a5a5a;}
.infographic-pyitertools .device-bar .dot:nth-child(1){background:#ff5f56;}
.infographic-pyitertools .device-body{padding:0.7rem 0.85rem;font-family:var(--mono-font);font-size:0.78rem;color:var(--ed-text);min-height:50px;max-height:190px;overflow-y:auto;}
.infographic-pyitertools .log-line{line-height:1.65;opacity:0;animation:it-fadein .2s ease forwards;}
@keyframes it-fadein{from{opacity:0;}to{opacity:1;}}
.infographic-pyitertools .log-empty{color:var(--ed-soft);}
.infographic-pyitertools .it-caption{text-align:center;font-size:0.85rem;color:var(--ink-soft);margin-top:0.9rem;}
@media (prefers-reduced-motion:reduce){.infographic-pyitertools *,.infographic-pyitertools *::before,.infographic-pyitertools *::after{animation-duration:.001ms!important;transition-duration:.001ms!important;}}
</style>
<div class="it-wrap">
<h1>enumerate() & itertools</h1>
<p class="it-sub">Fast, memory-efficient tools for looping — no manual index-tracking required.</p>
<div class="it-tabs">
<button class="it-tab-btn is-active" data-tab="enum">enumerate()</button>
<button class="it-tab-btn" data-tab="count">count()</button>
<button class="it-tab-btn" data-tab="cycle">cycle()</button>
<button class="it-tab-btn" data-tab="repeat">repeat()</button>
<button class="it-tab-btn" data-tab="chain">chain()</button>
<button class="it-tab-btn" data-tab="combperm">combinations / permutations</button>
</div>
<!-- ENUMERATE -->
<div class="it-panel" id="tabEnum">
<div class="code-line">for index, name in <strong>enumerate(names)</strong>: print(index, name)</div>
<div class="row"><input class="wide" id="enumInput" type="text" value="Alice, Bob, Charlie" /></div>
<div class="row"><button class="btn" id="enumRunBtn">Run</button></div>
<div class="chip-row" id="enumChips"><span class="log-empty" style="font-family:var(--mono-font); font-size:0.78rem; color:var(--ink-soft);">Hit Run to see the output.</span></div>
<p class="it-caption">Cleaner than <code style="font-family:var(--mono-font);">for i in range(len(names)): print(i, names[i])</code> — same result, no manual indexing.</p>
</div>
<!-- COUNT -->
<div class="it-panel is-hidden-tab" id="tabCount">
<div class="code-line">for i in <strong>itertools.count(start, step)</strong>: ...</div>
<div class="row">
<span>start</span><input id="countStart" type="text" value="10" />
<span>step</span><input id="countStep" type="text" value="2" />
<span>stop when ></span><input id="countLimit" type="text" value="20" />
</div>
<div class="row"><button class="btn" id="countRunBtn">Run</button></div>
<div class="chip-row" id="countChips"><span class="log-empty" style="font-family:var(--mono-font); font-size:0.78rem; color:var(--ink-soft);">Hit Run to see the output.</span></div>
<p class="it-caption">count() never stops on its own — infinite by design. Use case: invoice numbers, timestamps.</p>
</div>
<!-- CYCLE -->
<div class="it-panel is-hidden-tab" id="tabCycle">
<div class="code-line">for value in <strong>itertools.cycle(items)</strong>: ...</div>
<div class="row">
<input class="wide" id="cycleInput" type="text" value="A, B, C" />
</div>
<div class="row"><span>take</span><input id="cycleN" type="text" value="7" /><button class="btn" id="cycleRunBtn">Run</button></div>
<div class="chip-row" id="cycleChips"><span class="log-empty" style="font-family:var(--mono-font); font-size:0.78rem; color:var(--ink-soft);">Hit Run to see the output.</span></div>
<p class="it-caption">Loops the same items forever. Use case: rotating banners, playlists.</p>
</div>
<!-- REPEAT -->
<div class="it-panel is-hidden-tab" id="tabRepeat">
<div class="code-line">for x in <strong>itertools.repeat(elem, times)</strong>: print(x)</div>
<div class="row">
<span>elem</span><input id="repeatElem" type="text" value="Hello" />
<span>times</span><input id="repeatTimes" type="text" value="3" />
</div>
<div class="row"><button class="btn" id="repeatRunBtn">Run</button></div>
<div class="chip-row" id="repeatChips"><span class="log-empty" style="font-family:var(--mono-font); font-size:0.78rem; color:var(--ink-soft);">Hit Run to see the output.</span></div>
<p class="it-caption">The same value, over and over. Use case: placeholder values, mocking data.</p>
</div>
<!-- CHAIN -->
<div class="it-panel is-hidden-tab" id="tabChain">
<div class="code-line">list(<strong>chain(list_a, list_b)</strong>)</div>
<div class="row"><span>a =</span><input class="wide" id="chainA" type="text" value="1, 2" /></div>
<div class="row"><span>b =</span><input class="wide" id="chainB" type="text" value="3, 4" /></div>
<div class="row"><button class="btn" id="chainRunBtn">Run</button></div>
<div class="chip-row" id="chainChips"><span class="log-empty" style="font-family:var(--mono-font); font-size:0.78rem; color:var(--ink-soft);">Hit Run to see the output.</span></div>
<p class="it-caption">Two separate iterables treated as one, without actually merging them in memory. Use case: merging data lists.</p>
</div>
<!-- COMBINATIONS/PERMUTATIONS -->
<div class="it-panel is-hidden-tab" id="tabCombPerm">
<div class="code-line" id="cpCodeLine">list(<strong>combinations(items, r)</strong>)</div>
<div class="row">
<input class="wide" id="cpItems" type="text" value="a, b, c" />
</div>
<div class="row">
<span>r =</span><input id="cpR" type="text" value="2" />
<button class="toggle-btn is-selected" data-mode="comb">combinations</button>
<button class="toggle-btn" data-mode="perm">permutations</button>
</div>
<div class="row"><button class="btn" id="cpRunBtn">Run</button></div>
<div class="chip-row" id="cpChips"><span class="log-empty" style="font-family:var(--mono-font); font-size:0.78rem; color:var(--ink-soft);">Hit Run to see the output.</span></div>
<p class="it-caption" id="cpCaption">combinations: order doesn't matter, no repeats. Use case: forming teams or pairs.</p>
</div>
</div>
<script>
(function(){
var root = document.currentScript.closest('.infographic-pyitertools') || document.querySelector('.infographic-pyitertools');
var bodyAttr = document.body.getAttribute('data-darkmode');
var dark = bodyAttr === 'true' ? true : bodyAttr === 'false' ? false : (document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/) || [])[1] === 'true';
if (dark) root.setAttribute('data-theme', 'dark');
var tabBtns = root.querySelectorAll('.it-tab-btn');
var panels = {
enum: root.querySelector('#tabEnum'), count: root.querySelector('#tabCount'),
cycle: root.querySelector('#tabCycle'), repeat: root.querySelector('#tabRepeat'),
chain: root.querySelector('#tabChain'), combperm: root.querySelector('#tabCombPerm')
};
tabBtns.forEach(function (btn) {
btn.addEventListener('click', function () {
tabBtns.forEach(function (b) { b.classList.toggle('is-active', b === btn); });
var t = btn.dataset.tab;
Object.keys(panels).forEach(function (k) { panels[k].classList.toggle('is-hidden-tab', k !== t); });
});
});
function parseList(raw) { return raw.split(',').map(function (s) { return s.trim(); }).filter(function (s) { return s.length > 0; }); }
function makeChip(container, text, cls) {
var c = document.createElement('span');
c.className = 'chip' + (cls ? ' ' + cls : '');
c.textContent = text;
container.appendChild(c);
}
/* ---------------- enumerate ---------------- */
root.querySelector('#enumRunBtn').addEventListener('click', function () {
var items = parseList(root.querySelector('#enumInput').value);
var chips = root.querySelector('#enumChips');
chips.innerHTML = '';
items.forEach(function (v, i) { makeChip(chips, i + ' ' + v, 'out'); });
});
/* ---------------- count ---------------- */
root.querySelector('#countRunBtn').addEventListener('click', function () {
var start = parseFloat(root.querySelector('#countStart').value) || 0;
var step = parseFloat(root.querySelector('#countStep').value) || 1;
var limit = parseFloat(root.querySelector('#countLimit').value);
if (isNaN(limit)) limit = start + step * 10;
var chips = root.querySelector('#countChips');
chips.innerHTML = '';
var v = start, safety = 0;
while (v <= limit && safety < 200) { makeChip(chips, v, 'out'); v += step; safety++; }
if (safety >= 200) makeChip(chips, '…', null);
});
/* ---------------- cycle ---------------- */
root.querySelector('#cycleRunBtn').addEventListener('click', function () {
var items = parseList(root.querySelector('#cycleInput').value);
var n = parseInt(root.querySelector('#cycleN').value, 10) || 6;
var chips = root.querySelector('#cycleChips');
chips.innerHTML = '';
if (items.length === 0) return;
for (var i = 0; i < n; i++) makeChip(chips, items[i % items.length], 'out');
});
/* ---------------- repeat ---------------- */
root.querySelector('#repeatRunBtn').addEventListener('click', function () {
var elem = root.querySelector('#repeatElem').value.trim() || 'Hello';
var times = parseInt(root.querySelector('#repeatTimes').value, 10) || 3;
var chips = root.querySelector('#repeatChips');
chips.innerHTML = '';
for (var i = 0; i < Math.min(times, 50); i++) makeChip(chips, elem, 'out');
});
/* ---------------- chain ---------------- */
root.querySelector('#chainRunBtn').addEventListener('click', function () {
var a = parseList(root.querySelector('#chainA').value);
var b = parseList(root.querySelector('#chainB').value);
var chips = root.querySelector('#chainChips');
chips.innerHTML = '';
a.forEach(function (v) { makeChip(chips, v, null); });
b.forEach(function (v) { makeChip(chips, v, 'out'); });
});
/* ---------------- combinations / permutations ---------------- */
var cpMode = 'comb';
var cpToggles = root.querySelectorAll('#tabCombPerm .toggle-btn');
var cpCodeLine = root.querySelector('#cpCodeLine');
var cpCaption = root.querySelector('#cpCaption');
cpToggles.forEach(function (btn) {
btn.addEventListener('click', function () {
cpToggles.forEach(function (b) { b.classList.remove('is-selected'); });
btn.classList.add('is-selected');
cpMode = btn.dataset.mode;
if (cpMode === 'comb') {
cpCodeLine.innerHTML = 'list(<strong>combinations(items, r)</strong>)';
cpCaption.textContent = 'combinations: order doesn\'t matter, no repeats. Use case: forming teams or pairs.';
} else {
cpCodeLine.innerHTML = 'list(<strong>permutations(items, r)</strong>)';
cpCaption.textContent = 'permutations: every ordering counts separately. Use case: shuffling passwords, game states.';
}
});
});
function combinations(arr, r) {
var results = [];
function helper(start, combo) {
if (combo.length === r) { results.push(combo.slice()); return; }
for (var i = start; i < arr.length; i++) { combo.push(arr[i]); helper(i + 1, combo); combo.pop(); }
}
helper(0, []);
return results;
}
function permutations(arr, r) {
var results = [];
function helper(combo, used) {
if (combo.length === r) { results.push(combo.slice()); return; }
for (var i = 0; i < arr.length; i++) {
if (used[i]) continue;
used[i] = true; combo.push(arr[i]);
helper(combo, used);
combo.pop(); used[i] = false;
}
}
helper([], []);
return results;
}
root.querySelector('#cpRunBtn').addEventListener('click', function () {
var items = parseList(root.querySelector('#cpItems').value);
var r = parseInt(root.querySelector('#cpR').value, 10) || 2;
var chips = root.querySelector('#cpChips');
chips.innerHTML = '';
if (r > items.length || r < 1) { makeChip(chips, '(r out of range)', null); return; }
var results = cpMode === 'comb' ? combinations(items, r) : permutations(items, r);
if (results.length > 40) {
results.slice(0, 40).forEach(function (t) { makeChip(chips, '(' + t.join(', ') + ')', 'out'); });
makeChip(chips, '… ' + (results.length - 40) + ' more', null);
} else {
results.forEach(function (t) { makeChip(chips, '(' + t.join(', ') + ')', 'out'); });
}
});
})();
</script>
</div>⚡ Why itertools matters?
✅ Efficient
✅ Works well with large or infinite sequences
✅ Reduces boilerplate code