2
# coding: utf-8



def recherche_v1(x,tab):
    """
    tab est une liste d'éléments de types quelconques
    La fonction retourne True si x est dans tab, et false sinon
    """
    reponse = False
    for i in range(len(tab)):
        if tab[i] == x:
            reponse = True
    return reponse


def recherche_v2(x,tab):
    """
    tab est une liste d'éléments de types quelconques
    La fonction retourne True si x est dans tab, et false sinon
    """
    i = 0
    n = len(tab)
    while i < n and tab[i] != x:
        i = i + 1
    if i < n:
        return True
    else:
        return False


import timeit

x=int(input("saisir x : "))

print(timeit.timeit("recherche_v1(x,tab)", setup="from __main__ import recherche_v1", number=100000))
print(timeit.timeit("recherche_v2(x,tab)", setup="from __main__ import recherche_v2", number=100000))

Im getting:

Traceback (most recent call last):
  File "F:/Bureau/Nouveau dossier (3)/fcts_recherche_occur.py", line 36, in <module>
    print(timeit.timeit("recherche_v1(x,tab)", setup="from __main__ import recherche_v1", number=100000))
  File "C:\Users\arman\AppData\Local\Programs\Python\Python37\lib\timeit.py", line 232, in timeit
    return Timer(stmt, setup, timer, globals).timeit(number)
  File "C:\Users\arman\AppData\Local\Programs\Python\Python37\lib\timeit.py", line 176, in timeit
    timing = self.inner(it, self.timer)
  File "<timeit-src>", line 6, in inner
NameError: name 'x' is not defined
Keatinge
  • 4,330
  • 6
  • 25
  • 44
MrGame
  • 21
  • 1

2 Answers2

2

You need to provide all names you use in your timed code, in the setup. You currently only provide the recherche_v1 name, but not x or tab. Import those too:

tab = [...]  # you need to provide an object for the `tab` variable

print(
    timeit.timeit(
        "recherche_v1(x,tab)",
        setup="from __main__ import recherche_v1, x, tab",
        number=100000)
)

You have not defined tab anywhere, you'll need to provide a value for that separately.

Provided you are using Python 3.5 or newer, you could consider using the globals dictionary argument to timeit.timeit(), instead of using from __main__ import ... in a setup string:

print(
    timeit.timeit(
        "recherche_v1(x,tab)",
        globals={
            'recherche_v1': recherche_v1,
            'x': x,
            'tab': [...],   # a list value for tab is also needed
        },
        number=100000
    )
)

In either case, if you want to compare the performance of your two functions, consider generating a list of random values of a fixed, large, length, and picking x from the generated result. You want to compare different scenarios here and compare their timings:

  • x not being in the tab list
  • x being the first value in tab
  • x as the last value in tab

and you may want to compare these for tab lengths that grow by a magnitude each; so lists of length 1.000, 10.000, 100.000, etc.

There are some other issues you may want to address:

  • If you are using if <boolean test>: return True, else: return False, just return the boolean test result. So, in your case, instead of using:

    if i < n:
        return True
    else:
        return False
    

    You could just use

    return i < n
    

    and get the same result

  • In recherche_v1 are generating an index value between i and len(tab) with range(len(tab)), but then only use that index to get the values from tab. Rather than use a for loop on a range(), just loop on the list itself:

    for value in tab:
        if value == x:
    

I'm not sure if your goal is to compare how while compares to using a for loop, or if exiting the loop early makes a difference. If the latter, consider using return inside the loop; the moment you have found an equal value, you can exit your function with return True.

And finally, do also compare your functions against def recherche_integre(x, tab): return x in tab, for the built-in membership test for list objects.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Ty for the help. – MrGame May 06 '20 at 11:48
  • Glad to have been of help! Feel free to [accept **one** of the answers](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) if you feel it was useful to you. :-) Which one you pick is entirely up to you, and not picking any is also a valid option. – Martijn Pieters May 06 '20 at 11:49
1

timeit.timeit doesn't know about the name x because it only exists in the main code, not in setup or globals. You should explicitly provide it:

timeit.timeit(
    "recherche_v1(x,tab)",
    globals={
        'recherche_v1': recherche_v1,  # name from main code
        'x': x,   # name from main code
        'tab': ... # you never defined `tab`
    },
    number=100000
)

You could also import these names in setup, as you're doing now.

ForceBru
  • 43,482
  • 10
  • 63
  • 98