简体   繁体   中英

How to bypass if checking after matching once in python?

Suppose i have below statement :

for i in range(10000):
  if i==5:
    do_something_for_5()
  else:
    do_something()

so you can see python need to check 10000 times whether i equals to 5, and 9999 of checking is wasted. my question is, is there any trick that after catching 5 once, python will bypass if-checking and go directly to exec do_something()? somewhat like short-circuit the whole if checking. How to do that?

More. .

I don't think it is python problem, you see such checking pattern frequently in many languages.(compilers will optimize it?) The case is just for demo, I just hate to see the computer to check and check and check fruitless and just want to know the trick to avoid this. It likes such scenario: you know there is only one bad guy, and once you catch the bad guy, you withdraw the policemen and security checking to let others go directly, that will let process run faster.

More general code like this:

for member in member_list:
  if time_consuming_inspect(member)==special_character:#known there is only one candidate match in advance
    do_special_thing(member)
  else:
    do_common_thing(member)

Do a straightforward thing: break out of the loop after seeing 5, and run another loop to finish the work:

for i in range(10000):
    if i==5:
        do_something_for_5()
        break
    else:
        do_something()

for i in range(i+1, 10000):
    do_something()

One way would be to write something like this instead:

for i in range(4):
    do_something()

do_something_for_5()

for i in range(6, 10000):
    do_something()

If the special case for 5 need not be executed in order, then this will reduce duplication:

for i in itertools.chain(range(5), range(6, 10000)):
    print i

It sounds like you really want something like self-modifying code so that it never does the check again, but I would advise against that. There isn't much impact for an extra check.


Response to comment

The following is not recommended and is overkill for this example, but it does work. It uses a different function after the check for 5 has succeeded. Keep in mind the function that the variable is assigned to must be looked up, so I doubt there will be a speed increase. This probably has very limited use, but nevertheless:

do_something = None

def do_something_with_check(i):
    if i != 5:
        print 'Doing something with check.'
    else:
        do_something_for_5()
        global so_something
        do_something = do_something_without_check

def do_something_without_check(i):
    print 'Doing something without check.'

def do_something_for_5():
    print 'Doing something for 5.'

do_something = do_something_with_check

for i in range(10):
    do_something(i)

prints out:

Doing something with check.
Doing something with check.
Doing something with check.
Doing something with check.
Doing something with check.
Doing something for 5.
Doing something without check.
Doing something without check.
Doing something without check.
Doing something without check.
seenFive = False
for i in range(10000):
  if not seenFive and i==5:
    do_something_for_5()
    seenFive = True
  else:
    do_something()

You could not iterate over 5, and perform that function separately:

nums = range(10000) # list(range(10000)) on python3
nums.remove(5) # Get rid of 5 from the list.
do_something_for_5()
for i in nums:
    do_something()

I'm not sure this will help since the overhead of making the list might be more than checking if i==5 in each iteration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM