First of all, I am a beginner in Python trying to learn optimizations and proper coding standards.Here is a snippet of code that checks if a number follows the rule: first AND last N digits contain all unique numbers from 1 to N, but in any order. This also means that in either first N or last N digits, each number appears exactly once.import timestart_time = time.time()def is_pandigital(nr, n):    digits = ''.join(map(str, range(1, n + 1)))    nr = str(nr)    for i in digits:        if str(i) not in nr[0:9]:            return False        if str(i) not in nr[-9:]:            return False    return Trueassert is_pandigital(1423, 4) is Trueassert is_pandigital(1423, 5) is Falseassert is_pandigital(14235554123, 4) is Trueassert is_pandigital(14235552222, 4) is False # !importantassert is_pandigital(1444, 4) is Falseassert is_pandigital(123564987, 9) is Truepandigitals = []# this loop is strictly for benchmarking is_pandigitalfor i in range(100000, 999999):    if is_pandigital(i, 6):        pandigitals.append(i)print pandigitalsprint time.time() - start_time, secondsWhen running this, the result is:[123456, .......]2.968 secondsProcess finished with exit code 0The code seems to work fine, but it doesn't appear to be very efficient. Would you have any tips to improve it?  Any piece of code and/or idea would be highly appreciated.PS: I chose this loop so that any improvements to the is_pandigital function would be immediately obvious.Example of numbers I am looking for:321XXXXXXXXXXXXXXX132 - good321XXXXXXXXXXXXXXX133 - not good, because the last 3 digits dont contain 1, 2 and 3231 - good
Improve pandigital algorithm
python;optimization;beginner
You can rewrite your asserts without comparing to True and False:assert is_pandigital(1423, 4)assert not is_pandigital(1423, 5)assert is_pandigital(14235554123, 4)assert not is_pandigital(14235552222, 4) # !importantassert not is_pandigital(1444, 4)assert is_pandigital(123564987, 9)You can rewrite your benchmark with list comprehension:# this loop is strictly for benchmarking is_pandigitalpandigitals = [i for i in range(100000, 999999) if is_pandigital(i, 6)]Now for the algorithm itself, I must confess that I have troubles understanding what you want to do as you seem to be calling pandigital two different things. In any case, I have the feeling that something is wrong in your code, it seems like :   if str(i) not in nr[0:9]:        return False    if str(i) not in nr[-9:]:        return Falseshould be     if str(i) not in nr[0:n]:        return False    if str(i) not in nr[-n:]:        return Falseandassert not is_pandigital(9999912399999, 3)should provide you some hints.I'll go deeper in the code once you confirm that my understanding is correct.Edit : I have to go, no time to run benchmarks but here are the improvements. I kept different versions to that you can take ideas out of it.def is_pandigital(nr, n):    nr = str(nr)    beg=nr[0:n]    end=nr[-n:]    for i in map(str, range(1, n + 1)):        if i not in beg or i not in end:            return False    return Truedef is_pandigital(nr, n):    nr = str(nr)    beg=set(nr[0:n])    end=set(nr[-n:])    return beg==end and beg==set(map(str, range(1, n + 1)))