Reputation: 43
I have dictionary and a list. List only contains items, dictionary contains items and how many of a given item do I have. What I'm trying to do is to iterate through a dict and list, and if the key in a dict is the same as item in a list I only want to update its value by 1 but if there are no the same items I want to add the item form list to dict and set its value to 1.
stock = {apple: 1, banana: 4, orange: 10}
delivery = [apple, apple, grapefruit]
for k, v in stock.items():
for item in delivery:
if item == stock[k]:
stock[v] += 1
else:
stock.update({item:1})
Output should look sth like this:
stock = {apple: 3, banana: 4, orange: 10, grapefruit: 1}
However I'm getting message: dictionary changed size during iteration
Upvotes: 1
Views: 565
Reputation: 311
Also possible like this:
stock = {'apple': 1, 'banana': 4, 'orange': 10}
delivery = ['apple', 'apple', 'grapefruit']
stock.update({item: delivery.count(item) + stock.get(item,0)
for item in set(delivery)})
print(stock)
# {'apple': 3, 'banana': 4, 'orange': 10, 'grapefruit': 1})
Upvotes: 0
Reputation:
You can actually use Counter
from collections
which does exactly what you want.
from collections import Counter
stock = Counter({'apple': 1, 'banana': 4, 'orange': 10})
delivery = ['apple', 'apple', 'grapefruit']
stock.update(delivery)
Upvotes: 3
Reputation: 12015
You can use collections.counter
for this purpose
from collections import Counter
stock = Counter({'apple': 1, 'banana': 4, 'orange': 10})
delivery = ['apple', 'apple', 'grapefruit']
stock.update(delivery)
stock
# Counter({'orange': 10, 'banana': 4, 'apple': 3, 'grapefruit': 1})
Upvotes: 0
Reputation: 1
The best idea in this case will be to use a Counter collection instead of a standard dict (https://docs.python.org/2/library/collections.html) Check out the basic example given there:
# Tally occurrences of words in a list
cnt = Counter()
for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:
cnt[word] += 1
When using the standard dict you can loop over the list and along the following lines:
for v in delivery:
try:
stock[v] += 1
except KeyError:
stock[v] = 1
Alternatively you can use the *get * method of the dict and test for None.
Upvotes: 0
Reputation: 5354
You might want to reverse the order of enumeration and iterate over the list, adding items to the dict or increasing their value by one, as appropriate:
for item in delivery:
if item in stock:
stock[item] += 1
else:
stock[item] = 1
(note you can also use defaultdict(int) for your 'stock' dict object, so you don't even need the if/else and can do just:
for item in delivery:
stock[item] += 1
Upvotes: 0
Reputation: 26325
Using dict.get()
:
stock = {'apple': 1, 'banana': 4, 'orange': 10}
delivery = ['apple', 'apple', 'grapefruit']
for d in delivery:
stock[d] = stock.get(d, 0) + 1
print(stock)
Output:
{'apple': 3, 'banana': 4, 'orange': 10, 'grapefruit': 1}
Upvotes: 1
Reputation: 5414
You shouldn't change dict
or list
while iterating over it. You can write your code like:
stock = {'apple': 1, 'banana': 4, 'orange': 10}
delivery = ['apple', 'apple', 'grapefruit']
for item in delivery:
if item in stock:
stock[item] +=1
else:
stock[item] = 1
print(stock)
Upvotes: 4