How to make this Block of python code short and efficient

后端 未结 11 2463
天命终不由人
天命终不由人 2020-12-15 16:48

I am total newbie to programming and python. I was solving a problem. I found the solution but it seems like too slow.

    if n % 2 == 0 and n % 3 == 0 and\\         


        
相关标签:
11条回答
  • 2020-12-15 17:34

    Many of the above code examples are shorter, but (probably) not efficient enough:

    n%2 == 0 =>
        n%4 6 8... ==0
    n%3 == 0 =>
        n%3 6 9... ==0
    

    We can use only primes to check within the range:

    if all(n % i == 0 for i in [2,3,5,7,11,13,17,19])
    

    Furthermore, if n divides all from 2 to 20, it divides the LCM of 2 to 20.

    0 讨论(0)
  • 2020-12-15 17:36

    For variety, the way you could have used a loop for this is

    test = True
    for modulus in range(2, 21):
        if n % modulus != 0:
            test = False
            break
    if test:
        # Do stuff
    

    If you are comfortable with for-else, you can improve the brevity by

    for modulus in range(2, 21):
        if n % modulus != 0:
            break
    else:
        # Do stuff
    

    although that pattern may be unusual enough that you wouldn't want to use it.

    Another option is to write a helper function

    def is_divisible_by_integers_up_to(n, bound):
        for modulus in range(2, bound + 1):
            if n % modulus != 0:
                return False
        return True
    
    if is_divisible_by_integers_up_to(n, 20):
        # Do stuff
    

    However, this particular example is simple enough that doing all with a generator expression as described in the other answers is the best way to go.

    0 讨论(0)
  • 2020-12-15 17:38

    There's a trade-off between short and efficient.

    The Short way is if all(n % i == 0 for i in range(2, 21)):

    The Efficient way is to notice that things like n % 20 == 0 also mean that n % f == 0 where f is any factor of 20. For example, you can drop n % 2 == 0. So you'll end up with fewer comparisons which will run faster. In doing this you'll notice a pattern and you'll notice that the entire statement reduces to if n % 232792560 == 0! But that has now deeply embedded the 20 within it so will be difficult to unpick if you need a different upper limit.

    So you see that the efficient way is not so easy to read and maintain. So pick the one best suited to your requirements.

    0 讨论(0)
  • 2020-12-15 17:38
    if all(n % i == 0 for i in range(2, 21)):
    

    all accepts an iterable and returns True if all of its elements are evaluated to True, False otherwise. The n % i == 0 for i in range(2, 21) part returns an iterable with 19 True or False values, depending if n is dividable by the corresponding i value.

    0 讨论(0)
  • 2020-12-15 17:38

    I'm a very light python user myself, and I didn't know about all. Those solutions are pretty cool (and probably more efficient than the one I'm about to post). But just if you want to see another way to do it, here is another option:

    def IsDivUpTo20(n):
       for i in range(2, 21):
          if n % i != 0:
             return False
       return True
    

    And call it like so

    if IsDivUpTo20(50):
       #what to do if it is divisible
    else:
       #what to do if it isn't
    #for the example of 50, it'll be false and jump to the else part, but you can put any number of variable in there
    

    Functionally it is working pretty much the same way 'all' is, but if you aren't used to the fancy syntax and built-ins this one is a bit more intuitive.

    *Note: I use Python 3, not Python 2.7 as the question is tagged. I'm pretty sure this works in that version but if not, someone please correct me.

    0 讨论(0)
提交回复
热议问题