2

If you have a dictionary of integers:

d = {
  1:[0],
  2:[1], 
  3:[0,1,2,3,4],
  4:[0],
  5:[1], 
  6:[0,1,2,3,4],
  11:[0],
  22:[1], 
  33:[0,1,2,3,4],
  44:[0],
  55:[1], 
  66:[0,1,2,3,4]
}

You want to:

  1. Validate that the keys are between 0 and 25.

  2. Delete any keys that are outside of the range as they are not valid and will ruin the data set.

Dictionary keys are not naturally sorted.

Given, how would validate that your keys are in the required range? My try:

for x,y in d.items(): 
    if x<0 or x>25: 
         del d[x]

When ran I get the error:

RuntimeError: dictionary changed size during iteration 

How would I compensate for this?

William Merritt
  • 429
  • 1
  • 5
  • 12

3 Answers3

4

In your example, you are mutating the d while looping through it. This is bad.

The easiest way to do this if you don't need to change the original d is to use a dictionary comprehension:

d = {k: v for k, v in d.items() if 0 <= k <= 25}
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
2

If you want to delete keys while iterating, you need to iterate over a copy instead and pop keys that don't hold to your condition:

d = {1:[0], 2:[1], 3:[0,1,2,3,4], 4:[0], 5:[1], 6:[0,1,2,3,4], 11:[0], 22:[1], 33:[0,1,2,3,4], 44:[0], 55:[1], 66:[0,1,2,3,4]}

for k in d.copy(): # or list(d)
    if not 0 <= k <= 25:
        d.pop(k) # or del d[k]

Which Outputs:

{1: [0], 2: [1], 3: [0, 1, 2, 3, 4], 4: [0], 5: [1], 6: [0, 1, 2, 3, 4], 11: [0], 22: [1]}

As others have shown, reconstructing a new dictionary is always an easy way around this.

You can use a basic dict comprehension here:

{k: d[k] for k in d if 0 <= k <= 25}

Or even a functional approach with filter():

dict(filter(lambda x: 0 <= x[0] <= 25, d.items()))
RoadRunner
  • 25,803
  • 6
  • 42
  • 75
1

You can use a dictionary comprehension:

d = { 1:[0], 2:[1], 3:[0,1,2,3,4], 4:[0], 5:[1], 6:[0,1,2,3,4], 11:[0], 22:[1], 33:[0,1,2,3,4], 44:[0], 55:[1], 66:[0,1,2,3,4] }
new_d = {a:b for a, b in d.items() if a <= 25 and a >= 0}

Output:

{1: [0], 2: [1], 3: [0, 1, 2, 3, 4], 4: [0], 5: [1], 6: [0, 1, 2, 3, 4], 11: [0], 22: [1]}
Ajax1234
  • 69,937
  • 8
  • 61
  • 102