2
import csv

price = []
score = []
numPrice = []
numScore = []
with open(r'C:\Users\Testing\Desktop\Test.csv') as f:
    reader = csv.DictReader(f)
    for row in reader:
        price.append(row['price'])
        score.append(row['helpfulness_score'])
    for item in price:
        numPrice.append(float(item))
    for item in score:
        numScore.append(float(item))
finalDict = dict(zip(numScore,numPrice))                

for k in finalDict:
    if k > 5:
        finalDict.pop(k)

How can I remove all key and values less than 5? Right now I get the error 'RuntimeError: dictionary changed size during iteration' And is there a way to make this more efficient?

NoobPythoner
  • 87
  • 10
  • 1
    See [How to mutate dictionary while iterating over it](https://stackoverflow.com/questions/5384914/how-to-delete-items-from-a-dictionary-while-iterating-over-it) – DarrylG Oct 05 '19 at 14:23

2 Answers2

1

You cannot mutate a dict while you iterate over it.

You can either iterate over a copy of the keys:

for k in list(finalDict):
    if k > 5:
        finalDict.pop(k)

or use a dict comprehension instead with a filter that filters out keys greater than 5:

finalDict = {k: v for k, v in zip(numScore, numPrice) if k <= 5}
blhsing
  • 91,368
  • 6
  • 71
  • 106
1

You could try this instead of popping items before you store them inside the dictionary.

import csv

finalDict = {}
with open(r'C:\Users\Testing\Desktop\Test.csv') as f:
    reader = csv.DictReader(f)
    for row in reader:
        price = float(row['price']) # converting string to float
        score = float(row['helpfulness_score']) # converting string to float
        if score <= 5: # checking if the score is less than or equal to five
            finalDict[score] = price # stores the key, value pair

If you are very particular that you need to store all the key, value pairs inside the dictionary. Then you could avoid getting that error which is caused by trying to pop a dict item while iterating over it by using the following method.

Store the keys to a list and pop those keys right after you exit the iteration.

popList = [] # list to store the keys to pop
for k in finalDict:
    if k > 5:
        popList.append(k) # adding keys which will be popped later
for key in popList:
    finalDict.pop(key) # popping each key in the popList 

Under any circumstances unless you need all {key: value} pairs to be stored inside the finalDict for some processing, i would recommend only recommend the first method.

CodeIt
  • 3,492
  • 3
  • 26
  • 37