76

I've recently learned that the " % " sign is used to calculate the remainder of an integer in Python. However I was unable to determine if there's another operator or method to calculate percent in Python.

Like with " / " which will give you the quotient, if you just use a float for one of the integers, it will actually give you the answer like traditional division. So is there a method to work out percentage?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
nim6us
  • 797
  • 1
  • 6
  • 8
  • 3
    To be clear, do you mean `x * y / 100.0` or `(x/y) * 100.0`? Most of us read it as multiplication; Brian read it as division. – smci May 11 '17 at 22:51

8 Answers8

186

You could just divide your two numbers and multiply by 100. Note that this will throw an error if "whole" is 0, as asking what percentage of 0 a number is does not make sense:

def percentage(part, whole):
  return 100 * float(part)/float(whole)

Or with a % at the end:

 def percentage(part, whole):
  Percentage = 100 * float(part)/float(whole)
  return str(Percentage) + “%”

Or if the question you wanted it to answer was "what is 5% of 20", rather than "what percentage is 5 of 20" (a different interpretation of the question inspired by Carl Smith's answer), you would write:

def percentage(percent, whole):
  return (percent * whole) / 100.0
artscan
  • 2,340
  • 15
  • 26
Brian Campbell
  • 322,767
  • 57
  • 360
  • 340
  • 13
    You may want to add a if whole is 0 return 0, since otherwise this will throw an exception. I just ran into this so that's why I'm letting you know! – Andy Chase Oct 28 '12 at 02:42
  • 1
    @CarlSmith I didn't copy your answer; you will note that my version is not identical to yours. The second half was inspired by your different interpretation of the question, so you're right, I should have credited you for having inspired me to add the alternate interpretation of the question. – Brian Campbell Nov 15 '14 at 21:55
  • @CarlSmith If you notice, there are functional differences between our two answers, which you can see if you try them both out: `percentage(5, 20)` (my version) gives you `1.0`, as 5% of 20 is 1, while `percent(5, 20)` (your version) gives you `0.0`, which is incorrect as you use floor division. – Brian Campbell Nov 15 '14 at 22:02
  • Ok - no worries. I just noticed that your edit made my answer redundant, but not really deletable. I've deleted my original comments here and below to tidy up a bit. If you want to do the same? – Carl Smith Nov 16 '14 at 01:32
  • 8
    You don't need 2 casts, you can simply write `return 100.0 * part/whole`. – Agostino May 05 '15 at 00:49
  • @AndyChase if whole is 0, you shouldn't return 0 but rather either `None` or throw the error as we cannot divide something by 0. – PhaSath Mar 21 '22 at 13:01
  • On production, if ZeroDivisionError is undesired you just replace `whole` with `max(1, whole)` – Iuri Guilherme Feb 04 '23 at 03:02
46

There is no such operator in Python, but it is trivial to implement on your own. In practice in computing, percentages are not nearly as useful as a modulo, so no language that I can think of implements one.

Rafe Kettler
  • 75,757
  • 21
  • 156
  • 151
  • 2
    I'd add that even in math, a ratio is much more useful than a percentage. A percentage is just a way to represent a ratio that more people are familiar with. – loopbackbee Oct 29 '14 at 14:15
  • 51
    @nim6us: if all you need is to print the percentage then Python string formatting has such directive: `"{:.1%}".format(0.1234)` -> `'12.3%'`. – jfs Oct 29 '14 at 16:57
  • 8
    @jfs this remark is so good that IMO it deserves a separate answer. – hoefling Jan 13 '18 at 18:16
  • Why was this answer accepted? Brian Campbell's answer actually gave some code. – TheTechRobo the Nerd May 10 '20 at 12:46
9

use of %

def percent(expression="1000*12%") -> float:
    if "%" in expression:
        expression = expression.replace("%","")
        a, b = expression.split("*")
        a, b = float(a), float(b)
    return a*b/100

>>> percent("1500*20%")
300.0

Another way

p = lambda x : x/100
p20 = p(20)

>>> 150*p20
30.0
PythonProgrammi
  • 22,305
  • 3
  • 41
  • 34
5

Brian's answer (a custom function) is the correct and simplest thing to do in general.

But if you really wanted to define a numeric type with a (non-standard) '%' operator, like desk calculators do, so that 'X % Y' means X * Y / 100.0, then from Python 2.6 onwards you can redefine the mod() operator:

import numbers

class MyNumberClasswithPct(numbers.Real):
    def __mod__(self,other):
        """Override the builtin % to give X * Y / 100.0 """
        return (self * other)/ 100.0
    # Gotta define the other 21 numeric methods...
    def __mul__(self,other):
        return self * other # ... which should invoke other.__rmul__(self)
    #...

This could be dangerous if you ever use the '%' operator across a mixture of MyNumberClasswithPct with ordinary integers or floats.

What's also tedious about this code is you also have to define all the 21 other methods of an Integral or Real, to avoid the following annoying and obscure TypeError when you instantiate it

("Can't instantiate abstract class MyNumberClasswithPct with abstract methods __abs__,  __add__, __div__, __eq__, __float__, __floordiv__, __le__, __lt__, __mul__,  __neg__, __pos__, __pow__, __radd__, __rdiv__, __rfloordiv__, __rmod__, __rmul__,  __rpow__, __rtruediv__, __truediv__, __trunc__")
smci
  • 32,567
  • 20
  • 113
  • 146
  • 5
    Truly advanced stuff here that while not a good idea in this case, shows the true power of Python types! – Andy Chase Sep 29 '12 at 23:52
  • Reasons why I love python, THIS. Additionally, is it possible to not redefine all the abstract methods by doing some magic with cloning the *class* the existing `int` type, and setting the `__mod__` and `__mul__` operators, and then assign that to be the MyNumberClasswithPct ? – ThorSummoner Jan 04 '15 at 01:16
  • 1
    The gods will be angry if I do that – Pitto Jan 16 '15 at 19:01
  • Like so?: https://gist.github.com/thorsummoner/135c6a3c9b02b63c2e79 I originally was extending both numbers.Real and int, but I realized i just had to extend float. – ThorSummoner Jan 17 '15 at 00:18
  • @ThorSummoner yes but I specifically inherited from the abstract base class [numbers.Real](https://docs.python.org/2/library/numbers.html) instead of `float`, for safety. Try the other operators on your `Percent` object and see if you don't get any contradictions? Maybe using `numbers.Real` was too much paranoia. – smci Jan 17 '15 at 03:17
1

I have found that the most useful case for me is to compute the calculations as ratios and then printing the results formatting them as percentages thanks to Python formatting options:

result = 1.0/2.0            # result is 0.5
print(f'{result:.0%}')      # prints "50%"
Shunya
  • 2,344
  • 4
  • 16
  • 28
0

Very quickly and sortly-code implementation by using the lambda operator.

In [17]: percent = lambda part, whole:float(whole) / 100 * float(part)
In [18]: percent(5,400)
Out[18]: 20.0
In [19]: percent(5,435)
Out[19]: 21.75
PADYMKO
  • 4,217
  • 2
  • 36
  • 41
0
def percent(part, whole):
    try:
        return 100 * float(part) / float(whole)
    except ZeroDivisionError:
        return 0
paivatulio
  • 286
  • 2
  • 4
  • Hi paivatulio! Thanks for contributing your answer, but in the future please try to avoid "code-only" answers and add some explanation around you code snippets, see [How to Answer](https://stackoverflow.com/help/how-to-answer). Thanks! – joshmeranda Apr 07 '22 at 14:53
0

Just use this

score_in_percentage = round( score *100 , 2 )
print(f' {score_in_percentage}% ') #50%
Omar Essam El-Din
  • 1,415
  • 14
  • 17