<p>When I am writing code in Python, I often need to remove items from a list or other sequence type based on some criteria. I haven't found a solution that is elegant and efficient, as removing items from a list you are currently iterating through is bad.  For example, you can't do this:</p>

<pre><code>for name in names:
    if name[-5:] == 'Smith':
        names.remove(name)
</code></pre>

<p>I usually end up doing something like this:</p>

<pre><code>toremove = []
for name in names:
    if name[-5:] == 'Smith':
        toremove.append(name)
for name in toremove:
    names.remove(name)
del toremove
</code></pre>

<p>This is innefficient, fairly ugly and possibly buggy (how does it handle multiple 'John Smith' entries?). Does anyone have a more elegant solution, or at least a more efficient one? </p>

<p>How about one that works with dictionaries?</p>

Well, this is clearly an issue with the data structure you are using. Use a hashtable for example. Some implementations support multiple entries per key, so one can either pop the newest element off, or remove all of them.
But this is, and what you're going to find the solution is, elegance through a different data structure, not algorithm. Maybe you can do better if it's sorted, or something, but iteration on a list is your only method here.
edit:
one does realize he asked for 'efficiency'... all these suggested methods just iterate over the list, which is the same as what he suggested.