Dicts not being popped from list?
Question:
The context doesn’t matter too much, but I came across the problem that while trying to pop dict
objects from a list
, it wouldn’t delete all of them. I’m doing this to filter for certain values in the dict
objects, and I was left with things that should have been removed. Just to see what would happen, I tried deleting every item in the list
called accepted_auctions
(shown below), but it did not work.
for auction in accepted_auctions:
accepted_auctions.pop(accepted_auctions.index(auction))
print(len(accepted_auctions))
When I tested this code, print(len(accepted_auctions))
printed 44
into the console.
What am I doing wrong?
Answers:
It looks like you’re using a for loop to iterate over the list and calling pop on the list at the same time. This is generally not a good idea because the for loop uses an iterator to go through the items in the list, and modifying the list while you’re iterating over it can cause the iterator to become confused and not behave as expected.
One way to fix this is to create a new list that contains only the items that you want to keep, and then replace the original list with the new one. Here’s an example:
# Create an empty list to store the items that we want to keep
filtered_auctions = []
# Iterate over the items in the list
for auction in accepted_auctions:
# Check if the item meets the criteria for being kept
if some_condition(auction):
# If it does, append it to the filtered list
filtered_auctions.append(auction)
# Replace the original list with the filtered list
accepted_auctions = filtered_auctions
Another way to fix this is to use a while loop instead of a for loop. Here’s an example:
# Keep looping until the list is empty
while accepted_auctions:
# Pop the first item from the list
auction = accepted_auctions.pop(0)
# Check if the item meets the criteria for being kept
if some_condition(auction):
# If it does, append it to the filtered list
filtered_auctions.append(auction)
# Replace the original list with the filtered list
accepted_auctions = filtered_auctions
I hope this helps! Let me know if you have any other questions.
Modifying a list as you iterate over it will invalidate the iterator (because the indices of all the items are changing as you remove items), which in turn causes it to skip items. Don’t do that.
The easiest way to create a filtered list is via a list comprehension that creates a new list, e.g.:
accepted_auctions = [a for a in accepted_auctions if something(a)]
Here’s a simple example using a list comprehension to filter a list of ints to only the odd numbers:
>>> nums = list(range(10))
>>> nums
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> nums = [n for n in nums if n % 2]
>>> nums
[1, 3, 5, 7, 9]
The context doesn’t matter too much, but I came across the problem that while trying to pop dict
objects from a list
, it wouldn’t delete all of them. I’m doing this to filter for certain values in the dict
objects, and I was left with things that should have been removed. Just to see what would happen, I tried deleting every item in the list
called accepted_auctions
(shown below), but it did not work.
for auction in accepted_auctions:
accepted_auctions.pop(accepted_auctions.index(auction))
print(len(accepted_auctions))
When I tested this code, print(len(accepted_auctions))
printed 44
into the console.
What am I doing wrong?
It looks like you’re using a for loop to iterate over the list and calling pop on the list at the same time. This is generally not a good idea because the for loop uses an iterator to go through the items in the list, and modifying the list while you’re iterating over it can cause the iterator to become confused and not behave as expected.
One way to fix this is to create a new list that contains only the items that you want to keep, and then replace the original list with the new one. Here’s an example:
# Create an empty list to store the items that we want to keep
filtered_auctions = []
# Iterate over the items in the list
for auction in accepted_auctions:
# Check if the item meets the criteria for being kept
if some_condition(auction):
# If it does, append it to the filtered list
filtered_auctions.append(auction)
# Replace the original list with the filtered list
accepted_auctions = filtered_auctions
Another way to fix this is to use a while loop instead of a for loop. Here’s an example:
# Keep looping until the list is empty
while accepted_auctions:
# Pop the first item from the list
auction = accepted_auctions.pop(0)
# Check if the item meets the criteria for being kept
if some_condition(auction):
# If it does, append it to the filtered list
filtered_auctions.append(auction)
# Replace the original list with the filtered list
accepted_auctions = filtered_auctions
I hope this helps! Let me know if you have any other questions.
Modifying a list as you iterate over it will invalidate the iterator (because the indices of all the items are changing as you remove items), which in turn causes it to skip items. Don’t do that.
The easiest way to create a filtered list is via a list comprehension that creates a new list, e.g.:
accepted_auctions = [a for a in accepted_auctions if something(a)]
Here’s a simple example using a list comprehension to filter a list of ints to only the odd numbers:
>>> nums = list(range(10))
>>> nums
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> nums = [n for n in nums if n % 2]
>>> nums
[1, 3, 5, 7, 9]