0

I am taking in an integer value, finding the factorial of that value and trying to count the number of trailing zeros if any are present. For example:

def zeros(n):
    import math
    factorial = str(math.factorial(n))
    zeros_lst = [number if number == "0" (else) for number in factorial[::-1]]
    return len(zeros_lst)

The "else" in parenthesis is where the issue is occurring. I want to leave the loop if the as soon as it encounters a number that is not zero. I tried using break like you normally would, then looking up some examples but found nothing of similarity.

If someone knows how to break from a list comprehension or if is even possible that would be great. I am sure there are better ways to solve this problem, please post if you do.

martineau
  • 119,623
  • 25
  • 170
  • 301
eeskonivich
  • 121
  • 4
  • 15

4 Answers4

0

There is no "breaking" in list comprehensions, but there are other tricks, e.g. itertools.takewhile which iterates an iterable while a condition is satisfied:

>>> from itertools import takewhile
>>> 
>>> values = [7, 9, 11, 4, 2, 78, 9]
>>> list(takewhile(lambda x: x > 5, values))
[7, 9, 11]

In your case (I want to leave the loop if the as soon as it encounters a number that is not zero):

zeros_lst = list(takewhile(lambda x: x=="0", factorial[::-1]))
zvone
  • 18,045
  • 3
  • 49
  • 77
  • Isn't OP asking for trailing zeros? Is there `takeuntil`? Or `lambda x: x != '0'`? – joel goldstick Sep 20 '16 at 22:16
  • @joelgoldstick Ah, yes, `factorial[::-1]`, I'll update the answer. To bo honest, I do not understand the OP's actual intentions. – zvone Sep 20 '16 at 22:18
  • 1
    If you don't mind being a bit more obscure, you could use `"0".__eq__` rather than the `lambda` function. – Blckknght Sep 20 '16 at 22:21
  • @Blckknght LOL I was actually thinking about doing just that :D But obscure answers are probably not a good idea. – zvone Sep 20 '16 at 22:26
0

If someone knows how to break from a list comprehension

You can not break a list compression.

But you can modify your list comprehension with the if condition in for loop. With if, you can decide what values are needed to be the part of the list:

def zeros(n):
    import math
    factorial = str(math.factorial(n))
    # Check this line
    zeros_lst = [number for number in factorial[::-1] if number == '0']
    return len(zeros_lst)

It is better to use simple for loop. In fact for loops are faster than list comprehension in terms of performance. Check HERE the comparison I did for another question.

Even though list comprehension should be preferred as they are clean and more readable. Again, it is opinion based: Readability V/S Speed.

Suggestion:

Also, there is a easier way to achieve what you are doing via:

import math
def find_zeros_in_factorial(n):
    num_str = str(math.factorial(n))
    return len(num_str)-len(num_str.rstrip('0'))

The idea here is to subtract the length of the string with the length of string without zeroes at the end.

Community
  • 1
  • 1
Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
0

There is a more mathematical approach to this problem that is very simple and easy to implement. We only need to count how many factors of ten there are in factorial(n). We have an excess of factors of 2, so we choose to count factors of 5. It doesn't look as clean, but it avoids the computation of a factorial. The algorithm accounts for extra factors of 5 that show up in numbers like 25, 50, 125 and all of the rest.

def find_zeros_in_factorial(n):
    factors_of_5 = [n/5]
    while factors_of_5[-1] > 0:
        factors_of_5.append(factors_of_5[-1]/5)
    return sum(factors_of_5)
  • Hey so I need a little help understanding you code. I don't understand what your while loop is saying in english. Why are you using [-1]? Thanks for your time. – eeskonivich Sep 21 '16 at 22:23
  • In python, there is a convenient way to get the last element of the array. All you have to do is use the index -1 on an array and it returns the last element of the array. So for each loop in the while statement above, it will check if the last element is greater than 0. If it is then it takes the last element of the array, divides it by 5, and then appends the result to the end of the array. – Tyler Moncur Sep 22 '16 at 00:57
  • Thanks you for the clarification. I should of known that you were splicing into that list, just over thinking. – eeskonivich Sep 22 '16 at 19:42
0

Here is a function that will count the zeros, you just need to pass it your number. This saves the string operations you had before. It will terminate once there are no more trailing zeros.

def count_zeros(n):
    n_zeros = 0;
    while True:
        if n%10 == 0:
            n = n/10
            n_zeros+=1
        else:
            return n_zeros

print(count_zeros(math.factorial(12)))
Hefaestion
  • 203
  • 1
  • 8