<p>Is there any performance difference between tuples and lists when it comes to instantiation and retrieval of elements? </p>

[{'answer_id': 68638, 'author': 'ctcherry', 'author_id': 10322, 'author_profile': 'https://Stackoverflow.com/users/10322', 'pm_score': 2, 'selected': False, 'text': '<p>Tuples should be slightly more efficient and because of that, faster, than lists because they are immutable.</p>\n'}, {'answer_id': 68712, 'author': 'dF.', 'author_id': 3002, 'author_profile': 'https://Stackoverflow.com/users/3002', 'pm_score': 8, 'selected': False, 'text': '<p>In general, you might expect tuples to be slightly faster. However you should definitely test your specific case (if the difference might impact the performance of your program --  remember "premature optimization is the root of all evil").</p>\n\n<p>Python makes this very easy: <a href="https://docs.python.org/2/library/timeit.html" rel="noreferrer">timeit</a> is your friend.</p>\n\n<pre><code>$ python -m timeit "x=(1,2,3,4,5,6,7,8)"\n10000000 loops, best of 3: 0.0388 usec per loop\n\n$ python -m timeit "x=[1,2,3,4,5,6,7,8]"\n1000000 loops, best of 3: 0.363 usec per loop\n</code></pre>\n\n<p>and...</p>\n\n<pre><code>$ python -m timeit -s "x=(1,2,3,4,5,6,7,8)" "y=x[3]"\n10000000 loops, best of 3: 0.0938 usec per loop\n\n$ python -m timeit -s "x=[1,2,3,4,5,6,7,8]" "y=x[3]"\n10000000 loops, best of 3: 0.0649 usec per loop\n</code></pre>\n\n<p>So in this case, instantiation is almost an order of magnitude faster for the tuple, but item access is actually somewhat faster for the list! So if you\'re creating a few tuples and accessing them many many times, it may actually be faster to use lists instead.</p>\n\n<p>Of course if you want to <em>change</em> an item, the list will definitely be faster since you\'d need to create an entire new tuple to change one item of it (since tuples are immutable).</p>\n'}, {'answer_id': 68817, 'author': 'Mark Harrison', 'author_id': 116, 'author_profile': 'https://Stackoverflow.com/users/116', 'pm_score': 9, 'selected': True, 'text': '<p>The <a href="https://docs.python.org/3/library/dis.html" rel="noreferrer"><code>dis</code></a> module disassembles the byte code for a function and is useful to see the difference between tuples and lists.</p>\n\n<p>In this case, you can see that accessing an element generates identical code, but that assigning a tuple is much faster than assigning a list.</p>\n\n<pre><code>&gt;&gt;&gt; def a():\n...     x=[1,2,3,4,5]\n...     y=x[2]\n...\n&gt;&gt;&gt; def b():\n...     x=(1,2,3,4,5)\n...     y=x[2]\n...\n&gt;&gt;&gt; import dis\n&gt;&gt;&gt; dis.dis(a)\n  2           0 LOAD_CONST               1 (1)\n              3 LOAD_CONST               2 (2)\n              6 LOAD_CONST               3 (3)\n              9 LOAD_CONST               4 (4)\n             12 LOAD_CONST               5 (5)\n             15 BUILD_LIST               5\n             18 STORE_FAST               0 (x)\n\n  3          21 LOAD_FAST                0 (x)\n             24 LOAD_CONST               2 (2)\n             27 BINARY_SUBSCR\n             28 STORE_FAST               1 (y)\n             31 LOAD_CONST               0 (None)\n             34 RETURN_VALUE\n&gt;&gt;&gt; dis.dis(b)\n  2           0 LOAD_CONST               6 ((1, 2, 3, 4, 5))\n              3 STORE_FAST               0 (x)\n\n  3           6 LOAD_FAST                0 (x)\n              9 LOAD_CONST               2 (2)\n             12 BINARY_SUBSCR\n             13 STORE_FAST               1 (y)\n             16 LOAD_CONST               0 (None)\n             19 RETURN_VALUE\n</code></pre>\n'}, {'answer_id': 70968, 'author': 'tzot', 'author_id': 6899, 'author_profile': 'https://Stackoverflow.com/users/6899', 'pm_score': 5, 'selected': False, 'text': "<p>Tuples, being immutable, are more memory efficient; lists, for speed efficiency, overallocate memory in order to allow appends without constant <code>realloc</code>s. So, if you want to iterate through a constant sequence of values in your code (eg <code>for direction in 'up', 'right', 'down', 'left':</code>), tuples are preferred, since such tuples are pre-calculated in compile time.</p>\n<p>Read-access speeds should be the same (they are both stored as contiguous arrays in the memory).</p>\n<p>But, <code>alist.append(item)</code> is much preferred to <code>atuple+= (item,)</code> when you deal with mutable data. Remember, tuples are intended to be treated as records without field names.</p>\n"}, {'answer_id': 71295, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 3, 'selected': False, 'text': '<p>You should also consider the <code>array</code> module in the standard library if all the items in your list or tuple are of the same C type. It will take less memory and can be faster.</p>\n'}, {'answer_id': 22140115, 'author': 'Raymond Hettinger', 'author_id': 424499, 'author_profile': 'https://Stackoverflow.com/users/424499', 'pm_score': 8, 'selected': False, 'text': '<h2>Summary</h2>\n<p><em>Tuples tend to perform better than lists</em> in almost every category:</p>\n<ol>\n<li><p>Tuples can be <a href="https://en.wikipedia.org/wiki/Constant_folding" rel="noreferrer">constant folded</a>.</p>\n</li>\n<li><p>Tuples can be reused instead of copied.</p>\n</li>\n<li><p>Tuples are compact and don\'t over-allocate.</p>\n</li>\n<li><p>Tuples directly reference their elements.</p>\n</li>\n</ol>\n<h2>Tuples can be constant folded</h2>\n<p>Tuples of constants can be precomputed by Python\'s peephole optimizer or AST-optimizer.  Lists, on the other hand, get built-up from scratch:</p>\n<pre><code>    &gt;&gt;&gt; from dis import dis\n\n    &gt;&gt;&gt; dis(compile(&quot;(10, \'abc\')&quot;, \'\', \'eval\'))\n      1           0 LOAD_CONST               2 ((10, \'abc\'))\n                  3 RETURN_VALUE   \n \n    &gt;&gt;&gt; dis(compile(&quot;[10, \'abc\']&quot;, \'\', \'eval\'))\n      1           0 LOAD_CONST               0 (10)\n                  3 LOAD_CONST               1 (\'abc\')\n                  6 BUILD_LIST               2\n                  9 RETURN_VALUE \n</code></pre>\n<h2>Tuples do not need to be copied</h2>\n<p>Running <code>tuple(some_tuple)</code> returns immediately itself.  Since tuples are immutable, they do not have to be copied:</p>\n<pre><code>&gt;&gt;&gt; a = (10, 20, 30)\n&gt;&gt;&gt; b = tuple(a)\n&gt;&gt;&gt; a is b\nTrue\n</code></pre>\n<p>In contrast, <code>list(some_list)</code> requires all the data to be copied to a new list:</p>\n<pre><code>&gt;&gt;&gt; a = [10, 20, 30]\n&gt;&gt;&gt; b = list(a)\n&gt;&gt;&gt; a is b\nFalse\n</code></pre>\n<h2>Tuples do not over-allocate</h2>\n<p>Since a tuple\'s size is fixed, it can be stored more compactly than lists which need to over-allocate to make <code>append()</code> operations efficient.</p>\n<p>This gives tuples a nice space advantage:</p>\n<pre><code>&gt;&gt;&gt; import sys\n&gt;&gt;&gt; sys.getsizeof(tuple(iter(range(10))))\n128\n&gt;&gt;&gt; sys.getsizeof(list(iter(range(10))))\n200\n</code></pre>\n<p>Here is the comment from <em>Objects/listobject.c</em> that explains what lists are doing:</p>\n<pre class="lang-c prettyprint-override"><code>/* This over-allocates proportional to the list size, making room\n * for additional growth.  The over-allocation is mild, but is\n * enough to give linear-time amortized behavior over a long\n * sequence of appends() in the presence of a poorly-performing\n * system realloc().\n * The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...\n * Note: new_allocated won\'t overflow because the largest possible value\n *       is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t.\n */\n</code></pre>\n<h2>Tuples refer directly to their elements</h2>\n<p>References to objects are incorporated directly in a tuple object.  In contrast, lists have an extra layer of indirection to an external array of pointers.</p>\n<p>This gives tuples a small speed advantage for indexed lookups and unpacking:</p>\n<pre><code>$ python3.6 -m timeit -s \'a = (10, 20, 30)\' \'a[1]\'\n10000000 loops, best of 3: 0.0304 usec per loop\n$ python3.6 -m timeit -s \'a = [10, 20, 30]\' \'a[1]\'\n10000000 loops, best of 3: 0.0309 usec per loop\n\n$ python3.6 -m timeit -s \'a = (10, 20, 30)\' \'x, y, z = a\'\n10000000 loops, best of 3: 0.0249 usec per loop\n$ python3.6 -m timeit -s \'a = [10, 20, 30]\' \'x, y, z = a\'\n10000000 loops, best of 3: 0.0251 usec per loop\n</code></pre>\n<p><a href="https://github.com/python/cpython/blob/54ba556c6c7d8fd5504dc142c2e773890c55a774/Include/cpython/tupleobject.h#L9" rel="noreferrer">Here</a> is how the tuple <code>(10, 20)</code> is stored:</p>\n<pre class="lang-c prettyprint-override"><code>    typedef struct {\n        Py_ssize_t ob_refcnt;\n        struct _typeobject *ob_type;\n        Py_ssize_t ob_size;\n        PyObject *ob_item[2];     /* store a pointer to 10 and a pointer to 20 */\n    } PyTupleObject;\n</code></pre>\n<p><a href="https://github.com/python/cpython/blob/master/Include/listobject.h" rel="noreferrer">Here</a> is how the list <code>[10, 20]</code> is stored:</p>\n<pre class="lang-c prettyprint-override"><code>    PyObject arr[2];              /* store a pointer to 10 and a pointer to 20 */\n\n    typedef struct {\n        Py_ssize_t ob_refcnt;\n        struct _typeobject *ob_type;\n        Py_ssize_t ob_size;\n        PyObject **ob_item = arr; /* store a pointer to the two-pointer array */\n        Py_ssize_t allocated;\n    } PyListObject;\n</code></pre>\n<p>Note that the tuple object incorporates the two data pointers directly while the list object has an additional layer of indirection to an external array holding the two data pointers.</p>\n'}, {'answer_id': 52015256, 'author': 'Dev Aggarwal', 'author_id': 7061265, 'author_profile': 'https://Stackoverflow.com/users/7061265', 'pm_score': 4, 'selected': False, 'text': "<p>Here is another little benchmark, just for the sake of it..</p>\n\n<pre><code>In [11]: %timeit list(range(100))\n749 ns ± 2.41 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n\nIn [12]: %timeit tuple(range(100))\n781 ns ± 3.34 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n</code></pre>\n\n<hr>\n\n<pre><code>In [1]: %timeit list(range(1_000))\n13.5 µs ± 466 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n\nIn [2]: %timeit tuple(range(1_000))\n12.4 µs ± 182 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n</code></pre>\n\n<hr>\n\n<pre><code>In [7]: %timeit list(range(10_000))\n182 µs ± 810 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n\nIn [8]: %timeit tuple(range(10_000))\n188 µs ± 2.38 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n</code></pre>\n\n<hr>\n\n<pre><code>In [3]: %timeit list(range(1_00_000))\n2.76 ms ± 30.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n\nIn [4]: %timeit tuple(range(1_00_000))\n2.74 ms ± 31.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n</code></pre>\n\n<hr>\n\n<pre><code>In [10]: %timeit list(range(10_00_000))\n28.1 ms ± 266 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n\nIn [9]: %timeit tuple(range(10_00_000))\n28.5 ms ± 447 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n</code></pre>\n\n<p>Let's average these out:</p>\n\n<pre><code>In [3]: l = np.array([749 * 10 ** -9, 13.5 * 10 ** -6, 182 * 10 ** -6, 2.76 * 10 ** -3, 28.1 * 10 ** -3])\n\nIn [2]: t = np.array([781 * 10 ** -9, 12.4 * 10 ** -6, 188 * 10 ** -6, 2.74 * 10 ** -3, 28.5 * 10 ** -3])\n\nIn [11]: np.average(l)\nOut[11]: 0.0062112498000000006\n\nIn [12]: np.average(t)\nOut[12]: 0.0062882362\n\nIn [17]: np.average(t) / np.average(l)  * 100\nOut[17]: 101.23946713590554\n</code></pre>\n\n<p>You can call it almost inconclusive. </p>\n\n<p>But sure, tuples took <code>101.239%</code> the time, or <code>1.239%</code> extra time to do the job compared to lists.</p>\n"}, {'answer_id': 53385158, 'author': 'Divakar', 'author_id': 1613854, 'author_profile': 'https://Stackoverflow.com/users/1613854', 'pm_score': -1, 'selected': False, 'text': "<p>The main reason for Tuple to be very efficient in reading is because it's immutable. </p>\n\n<h2>Why immutable objects are easy to read?</h2>\n\n<p>The reason is tuples can be stored in the memory cache, unlike lists. The program always  read from the lists memory location as it is mutable (can change any time).</p>\n"}, {'answer_id': 64191136, 'author': 'Yilmaz', 'author_id': 10262805, 'author_profile': 'https://Stackoverflow.com/users/10262805', 'pm_score': 3, 'selected': False, 'text': '<p>Tuples perform better but if all the elements of tuple are immutable. If any element of a tuple is mutable a list or a function, it will take longer to be compiled. here I compiled 3 different objects:</p>\n<p><a href="https://i.stack.imgur.com/HfsPB.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/HfsPB.png" alt="enter image description here" /></a></p>\n<p>In the first example, I compiled a tuple. it loaded at the tuple as constant, it loaded and returned value. it took one step to compile. this is called <strong>constant folding</strong>. when I compiled a list with the same elements, it has to load each individual constant first, then it builds the list and returns it. in the third example, I used a tuple that includes a list. I timed each operation.</p>\n<p><a href="https://i.stack.imgur.com/mvl7O.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/mvl7O.png" alt="enter image description here" /></a></p>\n<p>-- <strong>MEMORY ALLOCATION</strong></p>\n<p>When mutable container objects such as lists, sets, dictionaries, etc are  created, and during their lifetime, the allocated capacity of these containers (the number of items they can contain) is greater than the number of elements in the container. This is done to make adding elements to the collection more efficient, and is called <strong>over-allocating</strong>. Thus size of the list doesn\'t grow every time we append an element - it only does so occasionally. Resizing a list is very expensive, so not resizing every time an item is added helps out but you don\'t want to overallocate too much as this has a memory cost.</p>\n<p>Immutable containers on the other hand, since their item count is fixed once they have been created, do not need this <strong>overallocation</strong> - so their storage efficiency is greater. As tuples get larger, their size increases.</p>\n<p>-- <strong>COPY</strong></p>\n<p>it does not make sense to make a shallow copy of immutable sequence because you cannot mutate it anyways. So copying tuple just returns itself, with the memory address. That is why copying tuple is faster</p>\n<h2>Retrieving elements</h2>\n<p>I timeD retrieving an element from a tuple and a list:</p>\n<p><a href="https://i.stack.imgur.com/On8U0.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/On8U0.png" alt="enter image description here" /></a></p>\n<p>Retrieving elements from a tuple are very slightly faster than from a list. Because, in CPython, tuples have direct access (pointers) to their elements, while lists need to first access another array that contains the pointers to the elements of the list.</p>\n'}]
['https://Stackoverflow.com/questions/68630', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4883/']