Skip to content

Commit b065840

Browse files
committed
looping pitfall
1 parent 503b140 commit b065840

1 file changed

Lines changed: 43 additions & 40 deletions

File tree

not_so_obvious_python_stuff.ipynb

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"metadata": {
33
"name": "",
4-
"signature": "sha256:be423e458dd8b1ac6a36f49330311cc1a1741127c5610a636969efddf6d91597"
4+
"signature": "sha256:02c6c63beb1de9373d69615a4ba37640a7b01c8f2d088dbfaa84bdaf3452f1c5"
55
},
66
"nbformat": 3,
77
"nbformat_minor": 0,
@@ -63,7 +63,8 @@
6363
"- [Python's LEGB scope resolution and the keywords `global` and `nonlocal`](#python_legb)\n",
6464
"- [When mutable contents of immutable tuples aren't so mutable](#immutable_tuple)\n",
6565
"- [List comprehensions are fast, but generators are faster!?](#list_generator)\n",
66-
"- [Public vs. private class methods and name mangling](#private_class)"
66+
"- [Public vs. private class methods and name mangling](#private_class)\n",
67+
"- [The consequences of modifying a list when looping through it](#looping_pitfall)"
6768
]
6869
},
6970
{
@@ -1299,14 +1300,31 @@
12991300
],
13001301
"prompt_number": 28
13011302
},
1303+
{
1304+
"cell_type": "markdown",
1305+
"metadata": {},
1306+
"source": [
1307+
"<br>\n",
1308+
"<br>\n",
1309+
"<a name='looping_pitfall'></a>\n",
1310+
"## The consequences of modifying a list when looping through it"
1311+
]
1312+
},
1313+
{
1314+
"cell_type": "markdown",
1315+
"metadata": {},
1316+
"source": [
1317+
"It can be really dangerous to modify a list when iterating through - it is a very common pitfall that can cause unintended behavour!"
1318+
]
1319+
},
13021320
{
13031321
"cell_type": "code",
13041322
"collapsed": false,
13051323
"input": [
13061324
"a = [1, 2, 3, 4, 5]\n",
13071325
"for i in a:\n",
1308-
" if not i % 2:\n",
1309-
" a.remove(i)\n",
1326+
" if not i % 2:\n",
1327+
" a.remove(i)\n",
13101328
"print(a)"
13111329
],
13121330
"language": "python",
@@ -1320,7 +1338,7 @@
13201338
]
13211339
}
13221340
],
1323-
"prompt_number": 1
1341+
"prompt_number": 3
13241342
},
13251343
{
13261344
"cell_type": "code",
@@ -1343,58 +1361,43 @@
13431361
]
13441362
}
13451363
],
1346-
"prompt_number": 7
1364+
"prompt_number": 4
13471365
},
13481366
{
1349-
"cell_type": "code",
1350-
"collapsed": false,
1351-
"input": [
1352-
"c = [2, 4, 5, 6]\n",
1353-
"for i in c:\n",
1354-
" if i % 2 != 0:\n",
1355-
" c.remove(i)\n",
1356-
"print(c)"
1357-
],
1358-
"language": "python",
1367+
"cell_type": "markdown",
13591368
"metadata": {},
1360-
"outputs": [
1361-
{
1362-
"output_type": "stream",
1363-
"stream": "stdout",
1364-
"text": [
1365-
"[2, 4, 6]\n"
1366-
]
1367-
}
1368-
],
1369-
"prompt_number": 6
1369+
"source": [
1370+
"<br>\n",
1371+
"<br>\n",
1372+
"**The solution** is that we are iterating through the list index by index, and if we remove one of the items in-between, we inevitably mess around with the indexing, look at the following example, and it will become clear:"
1373+
]
13701374
},
13711375
{
13721376
"cell_type": "code",
13731377
"collapsed": false,
13741378
"input": [
1375-
"not 4 % 2"
1379+
"b = [2, 4, 5, 6]\n",
1380+
"for index, item in enumerate(b):\n",
1381+
" print(index, item)\n",
1382+
" if not item % 2:\n",
1383+
" b.remove(item)\n",
1384+
"print(b)"
13761385
],
13771386
"language": "python",
13781387
"metadata": {},
13791388
"outputs": [
13801389
{
1381-
"metadata": {},
1382-
"output_type": "pyout",
1383-
"prompt_number": 9,
1390+
"output_type": "stream",
1391+
"stream": "stdout",
13841392
"text": [
1385-
"True"
1393+
"0 2\n",
1394+
"1 5\n",
1395+
"2 6\n",
1396+
"[4, 5]\n"
13861397
]
13871398
}
13881399
],
1389-
"prompt_number": 9
1390-
},
1391-
{
1392-
"cell_type": "code",
1393-
"collapsed": false,
1394-
"input": [],
1395-
"language": "python",
1396-
"metadata": {},
1397-
"outputs": []
1400+
"prompt_number": 7
13981401
}
13991402
],
14001403
"metadata": {}

0 commit comments

Comments
 (0)