12

I'm trying to construct a dictionary that contains a series of sets:

{Field1:{Value1, Value2, Value3}, Field2{Value4}}

The trouble is, I then wish to delete any fields from the dictionary that only have one value in the set. I have been writing code like this:

for field in FieldSet:
    if len(FieldSet[field]) == 1:
        del(FieldSet[field])

But receive the error "RuntimeError: dictionary changed size during execution". (Not surprising, since that's what I'm doing.) It's not the be-all and end-all if I have to knock together some sort of workaround, but is it possible to do this?

0

3 Answers 3

22

Iterate over the return value from .keys() instead. Since you get a list of keys back, it won't be affected by changing the dictionary after you've called it.

Sign up to request clarification or add additional context in comments.

5 Comments

That is to say, replace the first line with this: for field in FieldSet.keys():
I'm actually using python3, so the corrected line was: for field in list(FieldSet.keys()):
Shouldn't be necessary to convert to a list in this case.
Maybe, but it seemed to continue to throw the same error with the code Smashery suggested.
The list conversion is necessary in this case since the generator is lazily-evaluated, and thus on its own, it's susceptible to modifications mid-iteration. Converting to list pulls out all the keys before the iteration begins.
13

A sometimes-preferable alternative to changing FieldSet in place is sometimes (depending on the amount of alterations performed) to build a new one and bind it to the existing name:

FieldSet = dict((k, v) for k, v in FieldSet.iteritems()
                if len(v) != 1)

Comments

1

There is the pop method. It removes the element that a key calls. With respect to your example this looks like:

for field in FieldSet.keys():
    if len(FieldSet[field]) == 1:
        FieldSet.pop(field)

This is in python 3.2, but I'm not sure if it's a new feature: http://docs.python.org/dev/library/stdtypes.html#dict.pop

Just tried it and it works as advertised.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.