oduncu90
oduncu90

Reputation: 45

Python Faster 'If' Usage

I have a list:

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

There are multiple if usages that check a number is in the a list.

while True:
    if 3 in a:
        some_work1  #(different)
    
    if 4 in a:
        some_work2  #(different)
    
    if 8 in a:
        some_work3  #(different)
    
    if 11 in a:
        some_work4  #(different)

    if 12 in a:
        some_work5  #(different)

Are there any faster (less cpu usage) methods for these multiple if usages? (List a is always same. Also it does not change over iterations.). There is no dublicated items in the a list. Works do not overlap.

Python 3.8.7

Upvotes: 0

Views: 104

Answers (2)

kdcode
kdcode

Reputation: 522

option 1

You could use a dictionary whose keys are the number in a and values the corresponding function. Then you loop over them once and store the needed functions in an array (to_call). In the while loop you simply iterate over this array and call its members.

def some_work1():
   print("work1")

def some_work2():
   print("work2");

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
func = {3:some_work1,4:some_work2}

to_call = []
for k in func:
   if k in a:
      to_call.append(func[k])


while 1:
   for f in to_call:
      f();

Option 2

Write some kind of code generator that reads a and generates a .py file containing the function calls.

Upvotes: 0

Razzle Shazl
Razzle Shazl

Reputation: 1330

Use a set which has constant insert and retrieve times. In comparison, the in operator performs a linear search in your a every check.

I'm not exactly sure what your use-case is without seeing your larger code. I'm assuming your use-case treats a as a list of flags. As such, a set fits the bill.

a = [1, 2, 3, 4, 5, 6, 7, 8, 9 10, 11, 12]
a = set(a)  # pass an iterable

# or simply
a = {1, 2, 3, 4, 5, 6, 7, 8, 9 10, 11, 12}

# or built at runtime
a = set()
a.add(1)
a.add(2)

if 3 in a:
    some_work1 

If you want a more efficient switch statement, you have already found it. Python uses if..elif for this. This ensures each is evaluated in sequence with short-circuit. If you could match multiple outcomes, use a dict (e.g. {3: functor3, 4: functor4, ...}. A functor is a callable, ie it has a __call__() method defined. A lambda also satisfies this.

A set is an unordered collection that does not allow duplicates. It's like a dictionary but with the values removed, leaving just keys. As you know, dictionary keys are unique, and likewise members of a set are unique. Here we just want a set for performance.

Upvotes: 1

Related Questions