if/elif statements

Hello

I’ve been reading up a bit on basic Python features and read about if, elif, and else statements recently.
Would someone be able to briefly explain the reason for using elif statements following an if statement in certain circumstances instead of just using all if statements, and possibly give an example of such a circumstance where using elif instead of just if statements would be more efficient? I’m curious about how useful the elif statement can be, and in which case it could prove to be the most useful.

I’ve tried searching around the internet for a topic like this but with no avail.
Perhaps using elif instead of continuous if statements requires less processing and is therefore more efficient in a certain case?

no offense but you should be able to learn this on youtube or google.

but i will answer to my best anyway. hmm, im making this up right now lol so it will be very simple. also its not blender related but oh well. So say x is the user input to the promp “What is you favorite number inbetween 1 and 5” you could make your code

if x == 1:
print(‘Your favorite number is 1’)
elif x == 2:
print(‘Your favorite number is 2’)
elif x == 3:
print(‘Your favorite number is 3’)
elif x == 4:
print(‘Your favorite number is 4’)
elif x == 5:
print(‘Your favorite number is 5’)

so yea i guess you use it if you are choosing inbetween an couple of unknown variables is the best i know how to describe why you would use elif. i actually havent been using it alot lately but it is very commonly used.

wow sorry for my example not being formatted correctly, each print statement was supposed to be spaced over but for some reason it didnt save get posted that way…

Sometimes elif is the only option to get the result you want. Below is a function I wrote to get an index to an image buffer. Here self.x and self.y are the width and height of the image in pixels. If self.sculpty is true, then instead of ignoring x=64 on a self.x=64 image, we instead ignore x=63 and use that position on the image for x=64. I think the thing to consider is that elif is more efficient than “else: if” written separately.

It’s also more efficient in that a series of if elif elif elif will only be processed upto the first match. Separate if if if would test every condition, so if you know that if one condition is matched, the other’s won’t be (or won’t need doing) then elif’s are the right choice.

    def  _index(self, x, y):
        if x < 0 or y < 0 or x > self.x or y > self.y:
            return None
        if self.sculpty:
            # skip true last pixels and wrap
            # u = 1.0 and v = 1.0 back to last pixels
            if x == self.x - 1:
                if y != self.y:
                    return None
            if y == self.y - 1:
                if x != self.x:
                    return None
            if x == self.x:
                x = x - 1
            if y == self.y:
                y = y - 1
        elif x == self.x or y == self.y:
            return None
        return (x + y * self.x) * 4



            if x == self.x - 1:
                if y != self.y:
                    return None
            if y == self.y - 1:
                if x != self.x:
                    return None
            if x == self.x:
                x = x - 1
            if y == self.y:
                y = y - 1

I was obviously focused more on the results than efficiency when I wrote that bit. I could have done this:


            if x == self.x - 1:
                if y != self.y:
                    return None
            elif x == self.x:
                  x = x - 1
            if y == self.y - 1:
                if x != self.x:
                    return None
            elif y == self.y:
                y = y - 1

On getting index values for a full image, this would save self.x and self.y tests… So on a 512 x 512 image, that’s 1024 “if tests” less by using elif instead. Even better would be to reverse the order so self.x - 1 is the elif part, so the math is avoided on those cases too.

@Domino
On the Javaranch I learned not to use a return in an IF_statement … (only in very exceptional cases).

My answer would be
If you only use if then EACH if is checked.

If you use elif you may get earlier succes and the rest of the elif’s is NOT checked
Imagine that the chance of the first if is very big
and checking becomes more and more time consuming (second, third …) …

What would you do (hi hi)? Answer is hopfully if elif elif else …!

Well not sure how much java rules of thumb should affect Python programming, and even in Java that rule isn’t always the normal approach.

And as I’ve shown above I don’t even always follow my own rules of thumb, chances of getting me to follow a purists ones are slim and none :slight_smile:

Though having read that commentary I think I’m firmly in the simplifiers camp, though I’ve always thought of it as the lazy camp before… Do just enough then get out ASAP :wink:

To sum up the earlier posts, I feel inspired to say that elif can save processing time compared to multiple if statements. (I’m an amateur so please correct this if it’s wrong ;))


if value == 1: doThing1()
if value == 2: doThing2()
if value == 3: doThing3()
if value == 4: doThing4()

The above code will check “value” 4 times regardless of what value it contains, even if value = 1 it will still check to see if value = 2, 3 or 4.


if value == 1: doThing1()
elif value == 2: doThing2()
elif value == 3: doThing3()
elif value == 4: doThing4()

As soon as one of the if or elif statements is True then the code following that statement will be executed and all other elif statements will be ignored. If value = 1 then it will not bother to check whether value = 2, 3 or 4. This speeds up program execution time.

This can also be useful for filtering values…


if value < 1: doThing1()
elif value < 2: doThing2() #Program execution will not reach this point if 'value' is less than 1 so 'value' must be greater than or equal to 1 and less than 2.
elif value < 3: doThing3() #Program execution will not reach this  point if 'value' is less than 2 so 'value' must be greater than or equal to 2 and  less than 3.

The alternative to the above would be:


if value < 1: doThing1()
if value >= 1 and value < 2: doThing2()
if value >= 2 and value < 3: doThing3()

This would be slower, and looks much more messy.

did not see that one yet in python
but did anyone knows if there is an equivalent for a Case statement in python
so instead of using multiple if and elif you could sue a Case statement ?

There’s not an equivalent to case and switch in Python. Depending on the context, there are a few different ways to approach it - “if elif else”, dictionary lookups and polymorphism being the main ones.

never really use these before
do you have a simple examples showing the use of
dictionary lookups and polymorphism
that would complement well this thread

Dictionary example:

favourite = 3
numbers = { 1:'one', 2:'two', 3:'three', 4:'four', 5:'five' }
print("Your favourite number is %s" % numbers[favourite])

Not sure that there’s such a thing as a simple polymorphism example, but the animals one here should give you an idea.

I use polymorphism in my mesh generation functions for Primstar. I have a complex base class that uses get_vector(u, v) to convert UV co-ordinates into a 3D vector during the mesh generation. So by creating subclasses and just changing that one function in the class, I get new 3D shapes that all have the same function to call to generate them. So the actual defination for a new shape looks like this:

class AddUVPlane(bpy.types.Operator, AddUVBase):
    mesh_name = "Plane"
    bl_idname = "mesh.uv_shape_plane_add"
    bl_label = "Add plane UV shape"

    def get_vector(self, u, v):
        return (u - 0.5, v - 0.5, 0.0)

That avoids having all the shapes in one class and lots of if elif to select the correct vector generation. All the complex stuff is in the AddUVBase class, and I’m not risking introducing new bugs into tried and tested code if I want to add a new shape, say a cylinder…

class AddUVCylinder(bpy.types.Operator, AddUVBase):
    mesh_name = "Cylinder"
    bl_idname = "mesh.uv_shape_cylinder_add"
    bl_label = "Add cylinder UV shape"

    wrap_u = True

    def get_vector(self, u, v):
        a = pi + 2 * pi * u
        x = sin(a) / 2.0
        y = -cos(a) / 2.0
        return (x, y, v - 0.5)

wrap_u is also used by the mesh generation, to add a seam and close the loop in the u direction… I’m sure you can see how

if shape is plane: …
elif shape is cylinder: …

at various points in the code is going to get awfully messy pretty quickly.

well i never really worked with UV for scripting yet
don’t even understand how it is fully represented !

is there an intro or tut on that
might be interesting to learn more !

but i can see how the dictionnary one works
and might be usefull later on

nice examples given here
thanks

may be later on this spring
i might try to play with these UV image
might be fun to learn more
but right now there are so many ndw thigns coming along with 2.5
it’s hard to keep up!LOL

thanks anyway

I checked around quite a bit, I know how to use if statements with elif and else. I just need to know what use the elif statement is instead of using continuous if statements. Your example really doesn’t show why using elif is better, as I can achieve the same result by using if statements.

if x == 1:
do this()
if x == 2:
do this()

even if the first if statement is false, it’s still going to go to the next.

if x == 1:
do this()
elif x == 2:
do this()

Same with this example. If the first if statement is false, it will drop down to the elif statement. Basically what I’m looking for is a possible difference in processing performance.

with the elif statement if will will find the first occurence and then stop at that point
it won’t do all the elif statements

so it is faster that way i guess
and also easier to read and understand may be!

as the python docs describe,
the if-elif-else construct allows you to do a neatly formatted switch/case statement.
http://docs.python.org/tutorial/controlflow.html

if elif elif elif… seems equivalent to the switch/case statements in other languages, see the experiment below

An if … elif … elif … sequence is a substitute for the switch or case statements found in other languages.
quoted: http://docs.python.org/tutorial/controlflow.html

After looking at FunkyWyrm’s post I set up two similar scripts to experiment with, the first uses only if’s and the other uses elif’s:

if’s only:

var = 4

if var > 1: print("1")
print("first")

if var > 2: print("2")
print("second")

if var > 3: print("3")
print("third")

if var > 4: print("4")
print("fourth")

if var > 5: print("5")
print("end")

elif:

var = 4

if var > 1: print("1") 
elif var > 2: print("2")
elif var > 3: print("3")
elif var > 4: print("4")
elif var > 5: print("5")
    
print("end")

note: i found it wasn’t possible to put functions between elif statements, but wasn’t necessary for the experiment.

The first script printed:

1
first
2
second
3
third
fourth
end

The second script printed:

1
end

From my understanding of using elif’s, the script goes through the if and elif’s and once it finds a true statement, all others following from it will not be accessed. Therefore, this is pretty much the equivalent of the switch/case statements of other languages.

I’m guessing I’ll just be pointing out the obvious here, but I’m pretty new to Python so it’s a discovery to me and perhaps others. I see how using elif’s can be useful now instead of using only if’s.

edit: I see a few posts before this pointed the same thing out in simpler terms while I was still typing this post up :stuck_out_tongue:

Thanks for all of the help

You can place functions as part of the elif statements though. The inline method that I used was for readability, but only single command lines can be placed inline. Using a block you can place as much code as you want (sorry if stating the obvious, or should that be ‘if stating_the_obvious: print(“sorry”)’ ;))…


var = 4

if var > 1:
    print("1")
    print("first")
    #doThing1()
elif var > 2:
    print("2")
    print("second")
    #doThing2()
elif var > 3:
    print("3")
    print("third")
    #etc...
elif var > 4:
    print("4")
    print("fourth")
elif var > 5:
    print("5")
    print("end")

Thanks. I saw the inline statements, I was just noticing that functions [outside of the elif indentation] couldn’t interrupt the flow of the elif statements without causing an error :wink: