1

I'm blanking here. I want to grab all the users from the userbase, but then only loop through 10 of them (I'm leaving out code that would explain why I wouldn't just grab 10 users from the db in the first place).

users = User.objects.all()
i = 0
while i < 10:
    for user in users:
        if user.is_active:
            # do something
            i += 1

This is creating an endless loop... What stupid detail am I missing?

3
  • user.is_active condition is not true for 10 or more times. You need i += 1 under while i<10:. Right now, its under if user.is_active: Commented Jul 13, 2011 at 6:37
  • Do you have more than 10 active users in db? Commented Jul 13, 2011 at 6:40
  • Please note also you are iterating and doing something on all active users anyway since actions are in a for user in users loop (i.e. all) while i check is out that loop... Commented Jul 13, 2011 at 6:46

8 Answers 8

8

If you want to look for 10 active users, you're going to need to be a bit more clever.

for user in itertools.islice((x for x in users if x.is_active), 10):
  # do something
Sign up to request clarification or add additional context in comments.

Comments

2

Actually, it's not endless, it just runs through all users 10 times.

If you want the first 10 users (regardless if they're active or not):

while i < 10:
    user = users[i]
    if user.is_active:
        # do something
    i += 1

If you want the first 10 active users:

for user in users:
    if user.is_active:
        #do something
        i += 1
    if i >= 10:
        break

2 Comments

Your first statement is wrong, and your code sample will not work. It will create an endless loop if one of users[:10] is inactive.
Are you sure that this would work as expected? I mean that i increasing only when user active, but if there active and inactive users are mixed what then?
1

The while-loops condition is not evaluated until you've passed through all the users. You could remove the while and put an if i >= 10: break at the end of the for loop instead.

Comments

0

Try to follow your code on paper and see what it does. You'll notice that you're not grabbing the first ten users, but you are iterating over all the users ten times. The for-loop iterates over all user in users, and the while-loop repeats the for-loop ten times.

5 Comments

This would only be true if only one user was active.
@Tim I don't understand what you mean.
If ten users are active, then i is 10 at the end of the for loop, so the while condition becomes False after just one run through the while loop.
If there are 2 active users then the loop will execute 5 times. 3 users 4 times, etc.
@Tim & @Ignacio: Oh, I didn't notice the i += 1. :|
0

It seems like your code would be equivalent to

users = User.objects.filter(is_active=True)[:10]
for user in users:
    #do something

providing you have ten users.

Comments

0

Mabybe your i is never reaching 10. Maybe not even 10 of your users active.

Maybe i > 10 and the condition wasn't checked before that happens.

filter(lambda u:u.is_active, users)[:10]

Comments

0

Using list comprehension:

[user for user in User.objects.all() if user.is_active][:10]

And in case you need to perform any action on such users you can use again list comprehension:

[action(usr) for usr in [user for user in User.objects.all() if user.is_active][:10]]

Or map:

map(action, [user for user in User.objects.all() if user.is_active][:10])

Comments

0

Except for using special iterators (sometimes you import tens of lines of code to write your in a single one, you can call it being clever ^^, while you could do the same with 5 lines and no imports) I think this is the typical case to use break in a for loop

users = User.objects.all()
i = 0
for user in users:
    if user.is_active:
        #do something
        i += 1
    if i == 10:
        break
else:
    #do something if less than 10 active users (if necessary)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.