0

I'm doing an interactive map and after reading on the Internet, I'm trying to develop my learn towards an efficient way of programming. I wonder, is there a way to write more efficient this kinds of if_elif tree's ? I've read that one way is to make every conditions a def and store the conditions in a tuple ( 'cause is more efficiente than a list, and the values won't change). I've considered using ternary operator but don't know if is gonna be more efficient.

if direction == "w":
    point[POS_Y] -= 1
elif direction == "s":
    point[POS_Y] += 1
elif direction == "a":
    point[POS_X] -= 1
elif direction == "d":
    point[POS_X] += 1

Here's the code:

POS_X = 0
POS_Y = 1
MAP_WIDTH = 20
MAP_HEIGHT = 15
point = [3,7]
while 1: # i've read that Python is more efficient using a 1 instead of a True
    # def player_movement(point):
    
    print('+' + '-' * MAP_WIDTH * 3 + '+')
    
    for coordinate_y in range(MAP_HEIGHT):
        print('|',end='')
        for coordinate_x in range(MAP_WIDTH):
            if point[POS_X] == coordinate_x and point[POS_Y] == coordinate_y:
                print('  @',end='') # it works with ' @ ' as well, but in Visual Code doesn't see though
            else:
                print('   ',end='')
        print('|')
    print('+' + '-' * MAP_WIDTH * 3 + '+')
    
    
    # player_movement([3,8])
    direction = readchar.readchar().decode()
    
    if direction == "w":
        point[POS_Y] -= 1
    elif direction == "s":
        point[POS_Y] += 1
    elif direction == "a":
        point[POS_X] -= 1
    elif direction == "d":
        point[POS_X] += 1
Timus
  • 10,974
  • 5
  • 14
  • 28
  • 1
    Not sure about efficiency(performance wise), but you can definitely increase the readability by using switch statement. – sujeet Mar 22 '22 at 11:40
  • @8bitIcon switch? can you elaborate mate ? thanks in advance! – GonlinNocturno Mar 22 '22 at 11:46
  • there is nothing wrong with elif. The ones you use now are simple, i'd argue. – Kajbo Mar 22 '22 at 12:30
  • Under what conditions is if/elif speed a bottleneck when writing in python? Have you provfiled and *shown* that the efficiency matters here? If so python might not be the best tool; otherwise go for clarity as the others have said. – 2e0byo Mar 22 '22 at 13:17

2 Answers2

0

If you have python 3.10 and above you can use the switch statement.

Here is an example:

status = 404

def http_error(status):
    match status:
        case 400:
            return "Bad request"
        case 404:
            return "Not found"
        case 418:
            return "I'm a teapot"
        case _:
            return "Something's wrong with the internet"

This is called structural pattern matching and the link to the docs are here: https://docs.python.org/3.10/whatsnew/3.10.html#pep-634-structural-pattern-matching

As mentioned in the comments, this is no faster that if, elif statements from previous versions. So is important to mention.

D.L
  • 4,339
  • 5
  • 22
  • 45
0

After doing a quick test (python version 3.10.0) it seems that elif takes the most time, match comes second and using a dict is the fastest way.

test_elif

def test_elif():
    direction = random.choice(['w','a','s','d'])
    if direction == "w":
        point[1] -= 1
    elif direction == "s":
        point[1] += 1
    elif direction == "a":
        point[0] -= 1
    elif direction == "d":
        point[0] += 1
    return

test_match

def test_match():
    direction = random.choice(['w','a','s','d'])
    match direction:
        case "w":
            point[1] -= 1
        case "s":
            point[1] += 1
        case "a":
            point[0] -= 1
        case "d":
            point[0] += 1
    return

test_dict

def test_dict():
    direction = random.choice(['w','a','s','d'])
    md = modifiers[direction]
    point[md[0]] += md[1]
    return

setup

import random
modifiers = {
    "w": (1, -1),
    "s": (1, +1),
    "a": (0, -1),
    "d": (0, +1)
}
point = [0,0]

Tested with timeit.timeit(funcntion_call, setup=setup, number=1000000)

test_elif: 0.1586214000126347 seconds
test_match: 0.1482315000030212 seconds
test_dict: 0.13923519995296374 seconds

chill0r
  • 1,127
  • 2
  • 10
  • 26
  • nice!, I'll try using dicts, between dict and a tuple, which is faster considering I only need it to the conditionals. I'm trying to learn more about efficiency while I learn Python ( I'm studying Python Developing for AI) – GonlinNocturno Mar 22 '22 at 14:37