Svati
Svati

Reputation: 47

For loop running only once in python

Here is my code below:

import pymongo
import sys

client=pymongo.MongoClient('localhost',27017)
db=client.test 

try:              
     cursor= db.alb.find()         
     cursor1=db.img.find()             
     cntr=db.alb.count()        
     print "looping starts..."     
     for im in cursor1:                                                                                                        
         id1=im['_id']
         cnt=0
         print id1         
         for image in cursor:
             ig=image['images']
             print "image value:" , ig
             print "id value:" , id1
             if (id1 == ig):
                break;
             else:
                cnt=cnt+1
                print "count value", cnt
                if (cnt == cntr):
                   print "removing..."
                   db.img.remove({'_id':id1})
                   print id1
                   print cnt

except Exception as e:
     print "unexpected error", type(e),e

I have following data in alb collection :

id:0 images:366
id:1 images:367
id:2 images:368
id:3 images:369
id:4 images:370
id:5 images:380
id:6 images:371
id:7 images:372

I have below in img collection:

id:365
id:345
id:372
id:370
id:371
id:380
id:381

basically from the above code id:365 , id:345, id:381 should be removed from the img collection, but my code removes only id:365 in the img collection.

Please help me in correcting the errors in this code.....

Upvotes: 1

Views: 259

Answers (4)

Svati
Svati

Reputation: 47

import pymongo
import sys

client=pymongo.MongoClient('localhost',27017)
db=client.rop 

try:

   cntcur=db.albums.aggregate([{"$unwind":"$images"},{"$group":{"_id":"null","count":{'$sum':1}}}])
   cursor1=db.images.find()    

   for im in cursor1:         
       id1=int(im['_id'])
       cnt=0         
       cursor= db.albums.aggregate([{"$unwind":"$images"}])
       print id1         
       for image in cursor:
           print "moving to images collection"             
           ig=image['images']
           if (id1 == ig):
              break;
           else:
              cnt=cnt+1              
              if (cnt == cntr):
                 print "removing"  
                 db.images.remove({'_id':id1})                

 except Exception as e:
     print "unexpected error", type(e),e

for the above code i get string indices must be integer.I get in line ig=image['images']

Upvotes: 1

The6thSense
The6thSense

Reputation: 8335

This will work .This is due to the fact that a generator is provided when you call db.alb.find() the generator value is exhausted when you iterate over it in the for loop so second time when you iterate it there is no value in it so only for loop runs only once

import pymongo
import sys

client=pymongo.MongoClient('localhost',27017)
db=client.test 

try:              

    cursor1=db.img.find()             
    cntr=db.alb.count()        
    print "looping starts..."     
    for im in cursor1:                                                                                                        
        id1=im['_id']
        cnt=0
        print id1 
        cursor= db.alb.find()   #move it here      
        for image in cursor:
            ig=image['images']
            print "image value:" , ig
            print "id value:" , id1
            if (id1 == ig):
                break;
            else:
                cnt=cnt+1
                print "count value", cnt
                if (cnt == cntr):
                print "removing..."
                db.img.remove({'_id':id1})
                print id1
                print cnt

except Exception as e:
    print "unexpected error", type(e),e

Upvotes: 1

Vivek Sable
Vivek Sable

Reputation: 10223

I do not know where is your code fails. Write debug statement at right position so you can get where code fails.

e.g.

>>> for i in range(1,5):
...     print "Debug 1- i: ", i
...     for j in range(10,15):
...         print "Debug 1.1- j ", j
...         if j==13:
...             break
  1. In code print length of cursor1 (I think by count method)
  2. print cursor1 value after remove statement i.e db.img.remove({'_id':id1})

One more can you remove collections from the img after all process db.img.remove({'_id':id1})

create list which save id1 values and after process just you remove all id's of list from the db.img

remove_ids = []

# remove statement, append id value to list
remove_ids.append(id1)

# After process do 
for id in remove_ids:
    db.img.remove({'_id':id})

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409364

There are better ways of doing it. For example, what about something like this:

# Get all image identifiers
alb_images = [image['images'] for image in cursor]

# Find the ones to remove
images_to_remove = [im for im in cursor1 if im['_id'] not in alb_images]

After the above, the images_to_remove should contain the images to remove from your img collection.

[Note: This is probably not the most effective nor the most Pythonic way of doing it.]

Upvotes: 1

Related Questions