Why declare a list twice in __init__?
<p>I'm reading through the Python Docs, and, under <a href="https://docs.python.org/3/library/collections.abc.html#collections-abstract-base-classes" rel="nofollow">Section 8.4.1</a>,
I found the following <code>__init__</code> definition (abbreviated):</p>

<pre><code>class ListBasedSet(collections.abc.Set):
    ''' Alternate set implementation favoring space over speed
        and not requiring the set elements to be hashable. '''
    def __init__(self, iterable):
        self.elements = lst = []
        for value in iterable:
            if value not in lst:
                lst.append(value)
</code></pre>

<p>The part I don't get is the <code>self.elements = lst = []</code> line. Why the double assignment?</p>

<p>Adding some print statements:</p>

<pre><code>def __init__(self, iterable):
    self.elements = lst = []
    print('elements id:', id(self.elements))
    print('lst id:', id(lst))
    for value in iterable:
        if value not in lst:
            lst.append(value)
</code></pre>

<p>Declaring one:</p>

<pre><code>ListBasedSet(range(3))
elements id: 4741984136
lst id: 4741984136
Out[36]: &lt;__main__.ListBasedSet at 0x11ab12fd0&gt;
</code></pre>

<p>As expected, they both point to the same PyObject.</p>

<p>Is brevity the only reason to do something like this? If not, why? Something to do with reentrancy?</p>

<p>I'd call this a case of premature optimization; you don't save <em>that much</em> by eliminating the dot, especially for large input iterables; here's some timings:</p>

<p>Eliminating the dot:</p>

<pre><code>%timeit ListBasedSet(range(3))
The slowest run took 4.06 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 2.05 Âµs per loop

%timeit ListBasedSet(range(30))
100000 loops, best of 3: 18.5 Âµs per loop

%timeit ListBasedSet(range(3000))
10 loops, best of 3: 119 ms per loop
</code></pre>

<p>While, with the dot (i.e replace <code>lst</code> with <code>self.elements</code>:</p>

<pre><code>%timeit ListBasedSet(range(3))
The slowest run took 5.97 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 2.48 Âµs per loop

%timeit ListBasedSet(range(30))
10000 loops, best of 3: 22.8 Âµs per loop

%timeit ListBasedSet(range(3000))
10 loops, best of 3: 118 ms per loop
</code></pre>

<p>As you can see, as we increase the size of the input iterable, the difference in time pretty much disappears, the appending and membership testing pretty much cover any gains. </p>

python python-3.x documentation reentrancy