Python for loop skipping every other value
I have run into an odd problem in my django application where a for loop is skipping every other item. I have take a returned queryset and list()
ed to iterate over. The point of doing this is to remove items that are inside another list that is getting passed to the view via a POST variable. This view is an ajax request and returns a JSON list of items needed to be pushed to the page. upon the next request, the page passes the list of IDs of objects that are already on the page, so I can remove those from the queryset and pass back only new ones. I put several print statements throughout the problem portion of the code and figured out that the on the first request from the page, the list comes into the page empty because there aren't any displayed. The query runs and returns all the results which then get displayed on the page. On the second request, the list comes into the page with all of the id's, and this is where the problem occurs: As I loop through the queryset, checking to see if the id's are in the list, it only iterates over the odd values (which are removed) and returns a list of the even id'd objects to get displayed a second time on the page.
code:
items = list(listobj.getItems())
temp = items
print "Item List: ", temp
print "Rendered List: ", request.POST['rendered'].split(',')
for item in temp:
print "Item ID: ", str(item.id)
print "Rendered List: ", request.POST['rendered'].split(',')
if str(item.id) in request.POST['rendered'].split(','):
items.remove(item)
print "Removed Item: ", item.id
print "Unrendered Items: ", [item.id for item in items]
Results:
[02/Aug/2011 20:17:25] "GET /list/list HTTP/1.1" 200 6256
Item List: [<Item: Item object>, <Item: Item object>, <Item: Item object>, <Item: Item object>, <Item: Item object>, <Item: Item object>, <Item: Item object>, <Item: Item object>, <Item: Item object>]
Rendered List: [u'']
Item ID: 1
Rendered List: [u'']
Item ID: 2
Rendered List: [u'']
Item ID: 3
Rendered List: [u'']
Item ID: 4
Rendered List: [u'']
Item ID: 5
Rendered List: [u'']
Item ID: 6
Rendered List: [u'']
Item ID: 7
Rendered List: [u'']
Item ID: 8
Rendered List: [u'']
Item ID: 9
Rendered List: [u'']
Unrendered Items: [1, 2, 3, 4, 5, 6, 7, 8, 9]
[02/Aug/2011 20:17:25] "POST /items/ HTTP/1.1" 200 528
Item List: [<Item: Item object>, <Item: Item object>, <Item: Item object>, <Item: Item ob开发者_JAVA百科ject>, <Item: Item object>, <Item: Item object>, <Item: Item object>, <Item: Item object>, <Item: Item object>]
Rendered List: [u'1', u'2', u'3', u'4', u'5', u'6', u'7', u'8', u'9']
Item ID: 1
Rendered List: [u'1', u'2', u'3', u'4', u'5', u'6', u'7', u'8', u'9']
Removed Item: 1
Item ID: 3
Rendered List: [u'1', u'2', u'3', u'4', u'5', u'6', u'7', u'8', u'9']
Removed Item: 3
Item ID: 5
Rendered List: [u'1', u'2', u'3', u'4', u'5', u'6', u'7', u'8', u'9']
Removed Item: 5
Item ID: 7
Rendered List: [u'1', u'2', u'3', u'4', u'5', u'6', u'7', u'8', u'9']
Removed Item: 7
Item ID: 9
Rendered List: [u'1', u'2', u'3', u'4', u'5', u'6', u'7', u'8', u'9']
Removed Item: 9
Unrendered Items: [2, 4, 6, 8]
[02/Aug/2011 20:17:55] "POST /items/ HTTP/1.1" 200 252
temp
and items
refer to the same object, so when you do items.remove()
you're also modifying temp
. You probably want to do temp = items[:]
to copy the values of the items
list.
You should not be modifying a data structure while iterating over it.
Anyways, this is a more concise and performant code to do your operation:
items = list(listobj.getItems())
rendered = set((int(i) for i in request.POST['rendered'].split(',')))
unrendered = [item for item in items if item.id not in rendered]
精彩评论