Python: delete all variables except one for loops without contaminations
<pre><code>%reset
%reset -f
</code></pre>

<p>and </p>

<pre><code>%reset_selective a
%reset_selective -f a
</code></pre>

<p>are usefull Python alternative to the Matlab command "clear all", in which "-f" means "force without asking for confirmation" and "_selective" could be used in conjunction with </p>

<pre><code>who_ls
</code></pre>

<p>to selectively delete variables in workspace as clearly shown here <a href="https://ipython.org/ipython-doc/3/interactive/magics.html" rel="nofollow">https://ipython.org/ipython-doc/3/interactive/magics.html</a> .</p>

<p>Now I am managing loops in which I am going to define a large number of variables, for example</p>

<pre><code>for j in range(1000):
    a = crazy_function1()
    b = crazy_function2()
    ...
    m = crazy_function18()
    n = crazy_function19()
    ...
    z = crazy_functionN()
</code></pre>

<p>and at the end of each cycle I want to delete ALL variables EXCEPT the standard variables of the Python workspace and some of the variables I introduced (in this example only m and n). This would avoid contaminations and memory burdening hence it will make the code more efficient and safe.</p>

<p>I saw that "who_ls" result looks like a list, hence I thought at a loop that delete all variables that are not equal to m or n</p>

<pre><code>for j in range(1000):
    a = crazy_function1()
    b = crazy_function2()
    ...
    m = crazy_function18()
    n = crazy_function19()
    ...
    z = crazy_functionN()
    if who_ls[j] != m or who_ls[j] != n:
         %reset_selective -f who_ls[j]
</code></pre>

<p>but it doesn't work as who_ls looks as a list but it doesn't work as a list. How would you modify the last lines of code?
Is there anything like</p>

<pre><code> %reset_selective -f, except variables(m, n)
</code></pre>

<p>?</p>

<p>The normal approach to limiting the scope of variables is to use them in a function.  When the function is done, its <code>locals</code> disappear.</p>

<pre><code>In [71]: def foo():
    ...:     a=1
    ...:     b=2
    ...:     c=[1,2,3]
    ...:     d=np.arange(12)
    ...:     print(locals())
    ...:     del(a,b,c)
    ...:     print(locals())
    ...:     
In [72]: foo()
{'d': array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11]), 'c': [1, 2, 3], 'a': 1, 'b': 2}
{'d': array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])}
</code></pre>

<p>==================</p>

<p><code>%who_ls</code> returns a list, and can be used on the RHS, as in</p>

<pre><code>xx = %who_ls
</code></pre>

<p>and then that list can be iterated.  But note that this is a list of variable names, not the variables themselves.</p>

<pre><code>for x in xx: 
    if len(x)==1:
        print(x)
        # del(x)  does not work
</code></pre>

<p>shows all names of length 1. </p>

<p>======================</p>

<p>A simple way to use <code>%reset_selective</code> is to give the temporary variables a distinctive name, such as a prefix that regex can easily find.  For example</p>

<pre><code>In [198]: temp_a, temp_b, temp_c, x, y = 1,'one string',np.arange(10), 10, [1,23]
In [199]: who_ls
Out[199]: ['np', 'temp_a', 'temp_b', 'temp_c', 'x', 'y']
In [200]: %reset_selective -f temp 
In [201]: who_ls
Out[201]: ['np', 'x', 'y']
</code></pre>

<p>====================</p>

<p>Here's an example of doing this deletion from a list of names.  Keep in mind that there is a difference between the actual variable that we are trying to delete, and its name.</p>

<p>Make some variables, and list of names to delete</p>

<pre><code>In [221]: temp_a, temp_b, temp_c, x, y = 1,'one string',np.arange(10), 10, [1,23]
In [222]: dellist=['temp_a', 'temp_c','x']
</code></pre>

<p>Get the shell, and the <code>user_ns</code>.  <code>who_ls</code> uses the keys from <code>self.shell.user_ns</code>.</p>

<pre><code>In [223]: ip=get_ipython()
In [224]: user_ns=ip.user_ns

In [225]: %who_ls
Out[225]: ['dellist', 'i', 'ip', 'np', 'temp_a', 'temp_b', 'temp_c', 'user_ns', 'x', 'y']

In [226]: for i in dellist:
     ...:     del(user_ns[i])
     ...:     
In [227]: %who_ls
Out[227]: ['dellist', 'i', 'ip', 'np', 'temp_b', 'user_ns', 'y']
</code></pre>

<p>So we have to look up the names in the <code>user_ns</code> dictionary in order to delete them.  Note that this deletion code creates some variables, <code>dellist</code>, <code>i</code>, <code>ip</code>, <code>user_ns</code>.</p>

<p>==============</p>

<p>How many variables are you worried about?  How big are they?  Scalars, lists, numpy arrays.  A dozen or so scalars that can be named with letters  don't take up much memory.  And if there's any pattern in the generation of the variables, it may make more sense to collect them in a list or dictionary, rather than trying to give each a unique name.</p>

<p>In general it is better to use functions to limit the scope of variables, rather than use <code>del()</code> or <code>%reset</code>.  Occasionally if dealing with very large arrays, the kind that take a meg of memory and can create memory errors, I may use <code>del</code> or just <code>a=None</code> to remove them.  But ordinary variables don't need special attention (not even in an <code>ipython</code> session that hangs around for several days).</p>

python ipython