`For x in locals():` -- RuntimeError: Why does locals() change size?
<p>I have a function and want to get the arguments passed to it. I tried achieving this via <code>locals()</code>, but I end up getting the keys of <code>locals()</code>, not the value-pairs:</p>

<pre><code>&gt;&gt;&gt;def print_params(i,j,k):
    for x in locals():
        print(x)
&gt;&gt;&gt;print_params('a','b','c')
j
i
k     #&lt;--I want to get back 'a','b','c'.
</code></pre>

<p>I'd like to get the values instead of the keys, from <code>locals()</code>.</p>

<p>With a normal dict, I know I can do this:</p>

<pre><code>&gt;&gt;&gt; m = {
... 'a' : 'b',
... 'y' : 'z'}
&gt;&gt;&gt; m
{'a': 'b', 'y': 'z'}
&gt;&gt;&gt; for x in m:
...     print(x)
...
a      # &lt;--Keys
y
&gt;&gt;&gt; for x in m:
...     print(m[x])
...
b      # &lt;--Values
z
</code></pre>

<p>But, if I try this with <code>locals()</code>, it creates a RuntimeError. </p>

<pre><code>&gt;&gt;&gt; def print_args(i,j,k):
...     for x in locals():
...         print(locals()[x])
...
&gt;&gt;&gt; print_args('a','b','c')
b                          # &lt;--Got one!
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  File "&lt;stdin&gt;", line 2, in y
RuntimeError: dictionary changed size during iteration
</code></pre>

<p>Can someone explain what's happening? From the single value I got to print (before it errors out), I can see that the error arises when the loop attempts to iterate to the next element of <code>locals()</code>; then, as the dict has been modified, it loses its place. I can't make sense of why the dictionary size should change, though. I'm inferring that, on each pass through the <code>for</code> loop, the variable <code>x</code> is destroyed, then re-created for the next pass through the loop. However, this seems odd, since I would think it'd be more efficient to keep <code>x</code> "alive" and just re-assign it to the new value on each iteration. </p>

<p>Ultimately, I guess I could just do <code>local_args = locals()</code>, but I'm still curious as to what exactly is happening that prevents me from simply looping through <code>locals()</code>. I'm not sure if I'm right about <code>x</code> being destroyed/recreated; if I am, I have to wonder why that is, and if I'm not, then I'm even more curious as to what's happening.</p>

<p>When you call <code>for x in locals()</code>, <code>locals()</code> is evaluated then its first item is stored in <code>x</code>. <code>x</code> wasn't defined before, hence it is being added to the <code>locals</code> dictionary during the first loop and the second loop notices the change.</p>

<p>One way of workarounding this is to copy the <code>locals</code> dictionary beforehand as you've mentioned:</p>

<pre><code>def print_args(i,j,k):
    local_args = dict(locals())
    for x in local_args:
        print(local_args[x])

print_args('a','b','c')
</code></pre>

python iteration