The following contents are explained here with sample codes.
math.pi
math.degrees()
, math.radians()
math.sin()
, math.asin()
math.cos()
, math.acos()
math.tan()
, math.atan()
, math.atan2()
math.atan()
, math.atan2()
math.pi
Pi is provided as a constant in the math module. It is expressed as follows.math.pi
import math
print(math.pi)
# 3.141592653589793
math.degrees()
, math.radians()
Trigonometric and inverse trigonometric functions in the math module use the radian as the unit of angle.
Use math.degrees() and math.radians() to convert between radians (arc degree method) and degrees (degree method).
Math.degrees() converts from radians to degrees, and math.radians() converts from degrees to radians.
print(math.degrees(math.pi))
# 180.0
print(math.radians(180))
# 3.141592653589793
math.sin()
, math.asin()
The function to find the sine (sin) is math.sin() and the function to find the inverse sine (arcsin) is math.asin().
Here is an example of finding the sine of 30 degrees, using math.radians() to convert degrees to radians.
sin30 = math.sin(math.radians(30))
print(sin30)
# 0.49999999999999994
The sine of 30 degrees is 0.5, but there is an error because pi, an irrational number, cannot be calculated accurately.
If you wish to round to the appropriate number of digits, use the round() function or the format() method or the format() function.
Note that the return value of round() is a number (int or float), but the return value of format() is a string. If you want to use it for subsequent calculations, use round().
print(round(sin30, 3))
print(type(round(sin30, 3)))
# 0.5
# <class 'float'>
print('{:.3}'.format(sin30))
print(type('{:.3}'.format(sin30)))
# 0.5
# <class 'str'>
print(format(sin30, '.3'))
print(type(format(sin30, '.3')))
# 0.5
# <class 'str'>
The round() function specifies the number of decimal places as its second argument. Note that this is not strictly rounding. See the following article for details.
The format() method and format() function specify the number of decimal places in the formatting specification string. See the following article for details.
If you want to compare, you can also use math.isclose().
print(math.isclose(sin30, 0.5))
# True
Similarly, here is an example of finding the inverse sine of 0.5. math.asin() returns radians, which are converted to degrees with math.degrees().
asin05 = math.degrees(math.asin(0.5))
print(asin05)
# 29.999999999999996
print(round(asin05, 3))
# 30.0
math.cos()
, math.acos()
The function to find the cosine (cos) is math.cos(), and the function to find the inverse cosine (arc cosine, arccos) is math.acos().
Here is an example of finding the cosine of 60 degrees and the inverse cosine of 0.5.
print(math.cos(math.radians(60)))
# 0.5000000000000001
print(math.degrees(math.acos(0.5)))
# 59.99999999999999
If you wish to round to the appropriate digit, you can use round() or format() as with sine.
math.tan()
, math.atan()
, math.atan2()
The function to find the tangent (tan) is math.tan(), and the function to find the inverse tangent (arctan) is math.atan() or math.atan2().
Math.atan2() is described later.
An example of finding the tangent of 45 degrees and the inverse tangent of 1 degree is shown below.
print(math.tan(math.radians(45)))
# 0.9999999999999999
print(math.degrees(math.atan(1)))
# 45.0
Both math.atan() and math.atan2() are functions that return the inverse tangent, but they differ in the number of arguments and the range of return values.
math.atan(x) has one argument and returns arctan(x) in radians. The return value will be between -pi \ 2 and pi \ 2 (-90 to 90 degrees).
print(math.degrees(math.atan(0)))
# 0.0
print(math.degrees(math.atan(1)))
# 45.0
print(math.degrees(math.atan(-1)))
# -45.0
print(math.degrees(math.atan(math.inf)))
# 90.0
print(math.degrees(math.atan(-math.inf)))
# -90.0
In the example above, math.inf represents infinity.
math.atan2(y, x) has two arguments and returns arctan(y \ x) in radians. This angle is the angle (declination) that the vector from the origin to the coordinates (x, y) makes with the positive direction of the x axis in the polar coordinate plane, and the returned value is between -pi and pi (-180 to 180 degrees).
Since angles in the second and third quadrants can also be obtained correctly, math.atan2() is more appropriate than math.atan() when considering the polar coordinate plane.
Note that the order of the arguments is y, x, not x, y.
print(math.degrees(math.atan2(0, 1)))
# 0.0
print(math.degrees(math.atan2(1, 1)))
# 45.0
print(math.degrees(math.atan2(1, 0)))
# 90.0
print(math.degrees(math.atan2(1, -1)))
# 135.0
print(math.degrees(math.atan2(0, -1)))
# 180.0
print(math.degrees(math.atan2(-1, -1)))
# -135.0
print(math.degrees(math.atan2(-1, 0)))
# -90.0
print(math.degrees(math.atan2(-1, 1)))
# -45.0
As in the example above, the negative direction of the x-axis (y is zero and x is negative) is pi (180 degrees), but when y is negative zero, it is -pi (-180 degrees). Be careful if you want to handle the sign strictly.
print(math.degrees(math.atan2(-0.0, -1)))
# -180.0
Negative zeros are the result of the following operations
print(-1 / math.inf)
# -0.0
print(-1.0 * 0.0)
# -0.0
Integers are not treated as negative zeros.
print(-0.0)
# -0.0
print(-0)
# 0
Even when both x and y are zero, the result depends on the sign.
print(math.degrees(math.atan2(0.0, 0.0)))
# 0.0
print(math.degrees(math.atan2(-0.0, 0.0)))
# -0.0
print(math.degrees(math.atan2(-0.0, -0.0)))
# -180.0
print(math.degrees(math.atan2(0.0, -0.0)))
# 180.0
There are other examples where the sign of the result changes depending on negative zeros, such as math.atan2() as well as math.sin(), math.asin(), math.tan(), and math.atan().
print(math.sin(0.0))
# 0.0
print(math.sin(-0.0))
# -0.0
print(math.asin(0.0))
# 0.0
print(math.asin(-0.0))
# -0.0
print(math.tan(0.0))
# 0.0
print(math.tan(-0.0))
# -0.0
print(math.atan(0.0))
# 0.0
print(math.atan(-0.0))
# -0.0
print(math.atan2(0.0, 1.0))
# 0.0
print(math.atan2(-0.0, 1.0))
# -0.0
Note that the examples so far are the results of running the program in CPython. Note that other implementations or environments may handle negative zeros differently.
]]>The following is explained here, along with sample code.
math.e
**
operator, pow()
, math.pow()
math.sqrt()
math.exp()
math.log()
, math.log10()
, math.log2()
math.e
The base of the natural logarithm (Napier number) is provided as a constant in the math module, denoted by math.e.
import math
print(math.e)
# 2.718281828459045
**
operator, pow()
, math.pow()
To compute powers, use either the ** operator, the built-in function pow(), or math.pow().
The y-square of x is obtained as follows
x**y
pow(x, y)
math.pow(x, y)
print(2**4)
# 16
print(pow(2, 4))
# 16
print(math.pow(2, 4))
# 16.0
math.pow() converts the argument to a floating-point type. On the other hand, Python's built-in function pow() uses __pow()__ defined for each type.
For example, pow() allows complex types to be specified as arguments, but math.pow() cannot convert complex types to float types, resulting in an error.
print(pow(1 + 1j, 2))
# 2j
# print(math.pow(1 + 1j, 2))
# TypeError: can't convert complex to float
The Python built-in function pow() also allows a third argument, pow(x, y, z), which returns the remainder (remainder) of z to the y-power of x. It is the same calculation as pow(x, y) % z, but pow(x, y, z) is more efficient.
print(pow(2, 4, 5))
# 1
math.sqrt()
The square root (root) can be set to **0.5 using ** or math.sqrt().
print(2**0.5)
# 1.4142135623730951
print(math.sqrt(2))
# 1.4142135623730951
print(2**0.5 == math.sqrt(2))
# True
Like math.pow(), math.sqrt() converts arguments to floating-point types for processing, so specifying a type that cannot be converted to a float type will result in a TypeError.
print((-3 + 4j)**0.5)
# (1.0000000000000002+2j)
# print(math.sqrt(-3 + 4j))
# TypeError: can't convert complex to float
Also, math.sqrt() cannot process negative values, resulting in a ValueError.
print((-1)**0.5)
# (6.123233995736766e-17+1j)
# print(math.sqrt(-1))
# ValueError: math domain error
Note that when dealing with complex numbers, the example using the ** operator shows an error, but the cmath module provides a more accurate value. Negative values can also be handled.
import cmath
print(cmath.sqrt(-3 + 4j))
# (1+2j)
print(cmath.sqrt(-1))
# 1j
math.exp()
To calculate the power of the base of the natural logarithm (Napier number) e, use math.exp().
math.exp(x) returns x squared of e.
math.exp(x) is not equivalent to “math.e ** x” and math.exp(x) is more accurate.
print(math.exp(2))
# 7.38905609893065
print(math.exp(2) == math.e**2)
# False
math.log()
, math.log10()
, math.log2()
To compute the logarithmic function, use math.log(),math.log10(),math.log2().
math.log(x, y) returns the logarithm of x with y as the base.
print(math.log(25, 5))
# 2.0
If the second argument is omitted, the natural logarithm is shown below.
In mathematics, the natural logarithm (logarithm with Napier number e as the base), represented by log or ln, can be calculated by math.log(x).
print(math.log(math.e))
# 1.0
The ordinary logarithm (logarithm with base 10) can be calculated with math.log10(x), which is more accurate than math.log(x, 10).
print(math.log10(100000))
# 5.0
The binary logarithm (logarithm with base 2) can be calculated with math.log2(x), which is more accurate than math.log(x, 2).
print(math.log2(1024))
# 10.0
]]>The itertools module can also be used to generate permutations and combinations from lists (arrays), etc., and enumerate them.
The following is explained here, along with sample code.
math.factorial()
math.factorial()
scipy.special.perm()
itertools.permutations()
math.factorial()
scipy.special.comb()
itertools.combinations()
itertools.combinations_with_replacement()
As an example of utilizing permutations, the following is also explained.
If you want to generate a combination of elements of multiple listings instead of a single listing, use itertools.product() in the itertools module.
math.factorial()
The math module provides a function factorial() that returns the factorial.
import math
print(math.factorial(5))
# 120
print(math.factorial(0))
# 1
Non-integer, negative values will result in a ValueError.
# print(math.factorial(1.5))
# ValueError: factorial() only accepts integral values
# print(math.factorial(-1))
# ValueError: factorial() not defined for negative values
math.factorial()
Permutations are the number of cases where r are chosen from n different ones and placed in a row.
The total number of permutations, p, is obtained by the following equation using factorials.
p = n! / (n - r)!
It can be calculated as follows using the function math.factorial(), which returns the factorial. The ⌘ operator, which performs integer division, is used to return an integer type.
def permutations_count(n, r):
return math.factorial(n) // math.factorial(n - r)
print(permutations_count(4, 2))
# 12
print(permutations_count(4, 4))
# 24
SciPy provides a function scipy.special.perm() that returns the total number of permutations. A separate SciPy installation is required. Available from version 0.14.0.
from scipy.special import perm
print(perm(4, 2))
# 12.0
print(perm(4, 2, exact=True))
# 12
print(perm(4, 4, exact=True))
# 24
exact=False
The third argument is set as above by default and returns a floating point number. Note that if you want to get it as an integer, you need to set it as follows.exact=True
Note that only “import scipy” will not load the scipy.special module.
Execute perm() as “from scipy.special import perm” as in the above example, or execute scipy.special.perm() as “import scipy.special”.
itertools.permutations()
Not only total numbers, but also permutations can be generated and enumerated from lists (arrays), etc.
Use the permutations() function of the itertools module.
Passing an iterable (list or set type) as the first argument and the number of pieces to be selected as the second argument returns an iterator for that permutation.
import itertools
l = ['a', 'b', 'c', 'd']
p = itertools.permutations(l, 2)
print(type(p))
# <class 'itertools.permutations'>
To enumerate all of them, you can use a for loop.
for v in itertools.permutations(l, 2):
print(v)
# ('a', 'b')
# ('a', 'c')
# ('a', 'd')
# ('b', 'a')
# ('b', 'c')
# ('b', 'd')
# ('c', 'a')
# ('c', 'b')
# ('c', 'd')
# ('d', 'a')
# ('d', 'b')
# ('d', 'c')
Since it is a finite iterator, it can also be converted to a list type with list().
When the number of elements in the list is obtained with len(), it can be confirmed that it matches the total number of permutations calculated from the factorial.
p_list = list(itertools.permutations(l, 2))
print(p_list)
# [('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'a'), ('b', 'c'), ('b', 'd'), ('c', 'a'), ('c', 'b'), ('c', 'd'), ('d', 'a'), ('d', 'b'), ('d', 'c')]
print(len(p_list))
# 12
If the second argument is omitted, the permutation for selecting all elements is returned.
for v in itertools.permutations(l):
print(v)
# ('a', 'b', 'c', 'd')
# ('a', 'b', 'd', 'c')
# ('a', 'c', 'b', 'd')
# ('a', 'c', 'd', 'b')
# ('a', 'd', 'b', 'c')
# ('a', 'd', 'c', 'b')
# ('b', 'a', 'c', 'd')
# ('b', 'a', 'd', 'c')
# ('b', 'c', 'a', 'd')
# ('b', 'c', 'd', 'a')
# ('b', 'd', 'a', 'c')
# ('b', 'd', 'c', 'a')
# ('c', 'a', 'b', 'd')
# ('c', 'a', 'd', 'b')
# ('c', 'b', 'a', 'd')
# ('c', 'b', 'd', 'a')
# ('c', 'd', 'a', 'b')
# ('c', 'd', 'b', 'a')
# ('d', 'a', 'b', 'c')
# ('d', 'a', 'c', 'b')
# ('d', 'b', 'a', 'c')
# ('d', 'b', 'c', 'a')
# ('d', 'c', 'a', 'b')
# ('d', 'c', 'b', 'a')
print(len(list(itertools.permutations(l))))
# 24
In itertools.permutations(), elements are treated based on position, not value. Duplicate values are not taken into account.
l = ['a', 'a']
for v in itertools.permutations(l, 2):
print(v)
# ('a', 'a')
# ('a', 'a')
The same applies to the following functions, described below.
itertools.combinations()
itertools.combinations_with_replacement()
math.factorial()
The number of combinations is the number of r pieces to choose from n different pieces. The order is not considered as in permutations.
The total number of combinations c is obtained by the following equation.
c = n! / (r! * (n - r)!)
It can be calculated as follows using the function math.factorial(), which returns the factorial. The ⌘ operator, which performs integer division, is used to return an integer type.
def combinations_count(n, r):
return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))
print(combinations_count(4, 2))
# 6
scipy.special.comb()
SciPy provides a function scipy.special.comb() that returns the total number of permutations. A separate SciPy installation is required. Available from version 0.14.0. Note that scipy.misc.comb() does not implement the argument repetition described below.
from scipy.special import comb
print(comb(4, 2))
# 6.0
print(comb(4, 2, exact=True))
# 6
print(comb(4, 0, exact=True))
# 1
exact=False
As with scipy.special.perm(), the third argument is set as above by default and returns a floating-point number. Note that if you want to get it as an integer, you need to set it as follows.exact=True
The total number of duplicate combinations can also be obtained with the fourth argument, repetition. This is described below.
Again, note that only “import scipy” will not load the scipy.special module.
As in the above example, execute comb() as “from scipy.special import comb” or execute scipy.special.comb() as “import scipy.special”. The same applies to “scipy.misc”.
Another method that uses only the standard library and is faster than the method using math.factorial() is the following method.
from operator import mul
from functools import reduce
def combinations_count(n, r):
r = min(r, n - r)
numer = reduce(mul, range(n, n - r, -1), 1)
denom = reduce(mul, range(1, r + 1), 1)
return numer // denom
print(combinations_count(4, 2))
# 6
print(combinations_count(4, 0))
# 1
itertools.combinations()
It is possible to generate and enumerate all combinations from lists (arrays), etc. as well as total numbers.
Use the combinations() function of the itertools module.
Passing an iterable (list or set type) as the first argument and the number of pieces to be selected as the second argument returns the iterator for that combination.
l = ['a', 'b', 'c', 'd']
c = itertools.combinations(l, 2)
print(type(c))
# <class 'itertools.combinations'>
for v in itertools.combinations(l, 2):
print(v)
# ('a', 'b')
# ('a', 'c')
# ('a', 'd')
# ('b', 'c')
# ('b', 'd')
# ('c', 'd')
c_list = list(itertools.combinations(l, 2))
print(c_list)
# [('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd')]
print(len(c_list))
# 6
The number of duplicate combinations is the number of cases in which r are chosen from n different ones, allowing for duplicates.
The total number of duplicate combinations is equal to the number of combinations to choose (r) out of (n + r – 1) different ones.
Therefore, we can use the function defined above to calculate the total number of combinations.
def combinations_with_replacement_count(n, r):
return combinations_count(n + r - 1, r)
print(combinations_with_replacement_count(4, 2))
# 10
In “scipy.special.comb()” described above, the total number of duplicate combinations can be obtained by setting the fourth argument “repetition=True.
Note that the argument “repetition” is not implemented in “scipy.misc.comb()” in versions prior to “SciPy0.14.0”.
from scipy.special import comb
print(comb(4, 2, exact=True, repetition=True))
# 10
itertools.combinations_with_replacement()
It is possible to generate and enumerate all duplicate combinations from lists (arrays), etc. as well as total numbers.
Use the combinations_with_replacement() function in the itertools module.
Passing an iterable (list or set type) as the first argument and the number of pieces to be selected as the second argument returns an iterator for that overlapping combination.
h = itertools.combinations_with_replacement(l, 2)
print(type(h))
# <class 'itertools.combinations_with_replacement'>
for v in itertools.combinations_with_replacement(l, 2):
print(v)
# ('a', 'a')
# ('a', 'b')
# ('a', 'c')
# ('a', 'd')
# ('b', 'b')
# ('b', 'c')
# ('b', 'd')
# ('c', 'c')
# ('c', 'd')
# ('d', 'd')
h_list = list(itertools.combinations_with_replacement(l, 2))
print(h_list)
# [('a', 'a'), ('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'b'), ('b', 'c'), ('b', 'd'), ('c', 'c'), ('c', 'd'), ('d', 'd')]
print(len(h_list))
# 10
Itertools.permutations() makes it easy to create string permutations (anagrams).
s = 'arc'
for v in itertools.permutations(s):
print(v)
# ('a', 'r', 'c')
# ('a', 'c', 'r')
# ('r', 'a', 'c')
# ('r', 'c', 'a')
# ('c', 'a', 'r')
# ('c', 'r', 'a')
To combine a tuple of one character at a time into a string and make it into a list, do the following
anagram_list = [''.join(v) for v in itertools.permutations(s)]
print(anagram_list)
# ['arc', 'acr', 'rac', 'rca', 'car', 'cra']
The join() method, which concatenates elements of a list or tuple into a string, and the list comprehension notation are used.
]]>There is also a ternary operator that describes a conditional branch in one line. See the following article.
The basic form of the if statement is as follows
if Conditional expression 1:
`Processing to be performed if Expression 1 is True.`
elif Conditional expression 2:
`Processing to be performed when expression 1 is false and expression 2 is true.`
elif Expression 3:
`Process when expression 1 and 2 are false and expression 3 is true.`
...
else:
`Processing when all conditionals are false.`
The “elif” corresponds to the “else if” in C and other languages, and there may be any number of “elifs”.
If there is only one conditional expression or processing when false is not necessary, the “elif” and “else” blocks can be omitted.
Specify the condition with an operation that returns a bool type (true, false), such as a comparison operator.
Python comparison operators are as follows
operator | result |
---|---|
x < y |
true if x is less than y |
x <= y |
true if x is less than or equal to y |
x > y |
true if x is greater than y |
x >= y |
true if x is greater than or equal to y |
x == y |
true if x and y values are equal |
x != y
true if x and y values are not equal
x is y
true if x and y are the same object
x is not y
true if x and y are not the same object
x in y
true if x is contained in y
x not in y
true if x is not contained in y
Example. For convenience, it is defined as a function with the def statement.
def if_test(num):
if num > 100:
print('100 < num')
elif num > 50:
print('50 < num <= 100')
elif num > 0:
print('0 < num <= 50')
elif num == 0:
print('num == 0')
else:
print('num < 0')
if_test(1000)
# 100 < num
if_test(70)
# 50 < num <= 100
if_test(0)
# num == 0
if_test(-100)
# num < 0
The following can be written in a way that is unique to Python. See the following article for details.a < x < b
def if_test2(num):
if 50 < num < 100:
print('50 < num < 100')
else:
print('num <= 50 or num >= 100')
if_test2(70)
# 50 < num < 100
if_test2(0)
# num <= 50 or num >= 100
==
!=
The above is a comparison of values; to compare object identities, use the following
is
is not
For example, when comparing an integer and a floating-point number, “==” returns true if the values are equivalent, but “is” returns false because they are different objects.
i = 10
print(type(i))
# <class 'int'>
f = 10.0
print(type(f))
# <class 'float'>
print(i == f)
# True
print(i is f)
# False
It is also possible to make the condition whether a list or a string contains a specific element (character).
in
: includenot in
: not includingdef if_test_in(s):
if 'a' in s:
print('a is in string')
else:
print('a is NOT in string')
if_test_in('apple')
# a is in string
if_test_in('melon')
# a is NOT in string
The conditional expression of an if statement can be a number, list, or other object that is not of type bool (true, false).
if 10:
print('True')
# True
if [0, 1, 2]:
print('True')
# True
In the conditional expression of a Python if statement, the following objects are considered false.
- Constants defined to be false:
None
,false
- Zero in numeric type:
0
,0
,0j
,Decimal(0)
,Fraction(0, 1)
- Empty sequence or collection:
''
,()
,[]
,{}
,set()
,range(0)
Truth Value Testing — Built-in Types — Python 3.10.4 Documentation
Numbers representing zero, empty strings, lists, etc. are considered false; all others are considered true.
How the object is judged can be checked with bool().
print(bool(10))
# True
print(bool(0.0))
# False
print(bool([]))
# False
print(bool('False'))
# True
This can be used to simply write the process when the list is empty, for example.
def if_test_list(l):
if l:
print('list is NOT empty')
else:
print('list is empty')
if_test_list([0, 1, 2])
# list is NOT empty
if_test_list([])
# list is empty
Note that the string 'False' will also be true, because as shown in the example above, any string that is not empty in the string will be true.' To convert a specific string such as 'True' or 'False' to 1,0, use strtobool() in the distutils.util module.
The logical operators (and, or, not) can be used to handle logical conjunction, logical disjunction, and negation of multiple conditions.
operator | （Result (in the conditional expression of an if statement) |
---|---|
x and y |
true if both x and y are true |
x or y |
true if either x or y is true |
not x |
false if x is true, true if x is false |
def if_test_and_not(num):
if num >= 0 and not num % 2 == 0:
print('num is positive odd')
else:
print('num is NOT positive odd')
if_test_and_not(5)
# num is positive odd
if_test_and_not(10)
# num is NOT positive odd
if_test_and_not(-10)
# num is NOT positive odd
In fact, “x and y” and “x or y” do not return True or False, but either x or y. As long as they are used in conditional expressions in if statements, there is no need to worry about them, since they evaluate to either True or False. See the following article for details.
It is possible to use and and or more than once.
def if_test_and_not_or(num):
if num >= 0 and not num % 2 == 0 or num == -10:
print('num is positive odd or -10')
else:
print('num is NOT positive odd or -10')
if_test_and_not_or(5)
# num is positive odd or -10
if_test_and_not_or(10)
# num is NOT positive odd or -10
if_test_and_not_or(-10)
# num is positive odd or -10
When multiple conditional expressions are used by connecting them with “and” or “or” and each line becomes long, it is sometimes necessary to break the conditional expression and write it on multiple lines.
A line break can be made by using a backslash or by enclosing the entire line in parentheses.
def if_test_and_backslash(num):
if num >= 0 \
and not num % 2 == 0:
print('num is positive odd')
else:
print('num is NOT positive odd')
if_test_and_backslash(5)
# num is positive odd
def if_test_and_brackets(num):
if (num >= 0
and not num % 2 == 0):
print('num is positive odd')
else:
print('num is NOT positive odd')
if_test_and_brackets(5)
# num is positive odd
You can use a backslash to break a line as many times as you like. Likewise, you can break a line any number of times within parentheses. There is no indentation limit.
Note that this is a technique that can be used anywhere in Python code, not just in if statements.
]]>The following is explained here, along with sample code.
if ... elif ... else ...
Describe this in one lineSee the following article for more information on the normal if statement.
In Python, the ternary operator can be written as follows
Expression evaluated when the conditional expression is true if conditional expression else Expression evaluated when the conditional expression is false
If you want to switch values according to conditions, simply write each value as it is.
Value to return if conditional expression is true if conditional expression else Value to return if conditional expression is false
a = 1
result = 'even' if a % 2 == 0 else 'odd'
print(result)
# odd
a = 2
result = 'even' if a % 2 == 0 else 'odd'
print(result)
# even
If you want to switch processing according to conditions, describe each expression.
a = 1
result = a * 2 if a % 2 == 0 else a * 3
print(result)
# 3
a = 2
result = a * 2 if a % 2 == 0 else a * 3
print(result)
# 4
Expressions that do not return a value (expressions that return None) are also acceptable. Depending on the condition, one of the expressions is evaluated and the process is executed.
a = 1
print('even') if a % 2 == 0 else print('odd')
# odd
Equivalent to the following code written with a normal if statement.
a = 1
if a % 2 == 0:
print('even')
else:
print('odd')
# odd
Multiple conditional expressions can also be concatenated using logical operators (and, or, etc.).
a = -2
result = 'negative and even' if a < 0 and a % 2 == 0 else 'positive or odd'
print(result)
# negative and even
a = -1
result = 'negative and even' if a < 0 and a % 2 == 0 else 'positive or odd'
print(result)
# positive or odd
if ... elif ... else ...
One-line descriptionif ... elif ... else ...
There is no special way to write this on a single line. However, it can be realized by using another ternary operator in the expression that is evaluated when the conditional expression of the ternary operator is false. Image of nesting ternary operators.
However, it may be best not to use it extensively because it reduces readability.
a = 2
result = 'negative' if a < 0 else 'positive' if a > 0 else 'zero'
print(result)
# positive
a = 0
result = 'negative' if a < 0 else 'positive' if a > 0 else 'zero'
print(result)
# zero
a = -2
result = 'negative' if a < 0 else 'positive' if a > 0 else 'zero'
print(result)
# negative
The following conditional expression can be interpreted in the following two ways, but is treated as the former (1).
A if condition 1 else B if condition 2 else C
1. A if condition 1 else ( B if condition 2 else C )
2. ( A if condition 1 else B ) if condition 2 else C
A concrete example is as follows. The first expression is regarded as if it were the second.
a = -2
result = 'negative' if a < 0 else 'positive' if a > 0 else 'zero'
print(result)
# negative
result = 'negative' if a < 0 else ('positive' if a > 0 else 'zero')
print(result)
# negative
result = ('negative' if a < 0 else 'positive') if a > 0 else 'zero'
print(result)
# zero
A useful use of the ternary operator is when processing lists in list comprehension notation.
By combining the ternary operator and list comprehension notation, it is possible to replace elements of a list or perform some other processing depending on the conditions.
l = ['even' if i % 2 == 0 else i for i in range(10)]
print(l)
# ['even', 1, 'even', 3, 'even', 5, 'even', 7, 'even', 9]
l = [i * 10 if i % 2 == 0 else i for i in range(10)]
print(l)
# [0, 1, 20, 3, 40, 5, 60, 7, 80, 9]
For more information on list comprehension notation, see the following article.
The ternary operator, which can be described concisely even in an anonymous function (lambda expression), is useful.
get_odd_even = lambda x: 'even' if x % 2 == 0 else 'odd'
print(get_odd_even(1))
# odd
print(get_odd_even(2))
# even
Note that, although unrelated to the ternary operator, the above example assigns a name to the lambda expression. Therefore, automatic checking tools such as Python's coding convention PEP8 may generate a Warning.
This is because PEP8 recommends the use of def when assigning names to functions.
The concept of PEP8 is as follows
This section explains how to swap the rows and columns of this two-dimensional array.
.T
Transpose with this.pandas.DataFrame
Convert to this.T
Transpose with this.It is easier to use NumPy or pandas, but if you do not want to import NumPy or pandas just for transposition, you can use the zip() function to transpose.
The original two-dimensional array is defined as follows
import numpy as np
import pandas as pd
l_2d = [[0, 1, 2], [3, 4, 5]]
Generate a NumPy array ndarray from the original two-dimensional array and get the transposed object with the .T attribute.
If you want a Python list-type object in the end, further convert it to a list with the tolist() method.
arr_t = np.array(l_2d).T
print(arr_t)
print(type(arr_t))
# [[0 3]
# [1 4]
# [2 5]]
# <class 'numpy.ndarray'>
l_2d_t = np.array(l_2d).T.tolist()
print(l_2d_t)
print(type(l_2d_t))
# [[0, 3], [1, 4], [2, 5]]
# <class 'list'>
In addition to the .T attribute, the ndarray method transpose() and the function numpy.transpose() can also be used.
Generate a pandas.DataFrame from the original two-dimensional array and get the transposed object with the .T attribute.
If you want a Python list-type object in the end, get numpy.ndarray with the values attribute, and then convert it to a list with the tolist() method.
df_t = pd.DataFrame(l_2d).T
print(df_t)
print(type(df_t))
# 0 1
# 0 0 3
# 1 1 4
# 2 2 5
# <class 'pandas.core.frame.DataFrame'>
l_2d_t = pd.DataFrame(l_2d).T.values.tolist()
print(l_2d_t)
print(type(l_2d_t))
# [[0, 3], [1, 4], [2, 5]]
# <class 'list'>
Transposes a two-dimensional array using the built-in function zip().
zip() is a function that returns an iterator that summarizes the elements of multiple iterables (lists, tuples, etc.). It is used when running multiple lists in a for loop, for example.
In addition, the function uses a mechanism whereby the list can be expanded and passed if the function argument is marked with an asterisk.
Transpositions can be made as follows.
l_2d_t_tuple = list(zip(*l_2d))
print(l_2d_t_tuple)
print(type(l_2d_t_tuple))
# [(0, 3), (1, 4), (2, 5)]
# <class 'list'>
print(l_2d_t_tuple[0])
print(type(l_2d_t_tuple[0]))
# (0, 3)
# <class 'tuple'>
As it is, the elements inside are tuples. Therefore, if you want to make it a list, use list(), which converts a tuple to a list in list comprehension notation.
l_2d_t = [list(x) for x in zip(*l_2d)]
print(l_2d_t)
print(type(l_2d_t))
# [[0, 3], [1, 4], [2, 5]]
# <class 'list'>
print(l_2d_t[0])
print(type(l_2d_t[0]))
# [0, 3]
# <class 'list'>
The following is a step-by-step breakdown of the process.
The elements of the list are expanded with an asterisk, the expanded elements are grouped together with the zip() function, and then the tuple is converted to a list with list comprehension notation.
print(*l_2d)
# [0, 1, 2] [3, 4, 5]
print(list(zip([0, 1, 2], [3, 4, 5])))
# [(0, 3), (1, 4), (2, 5)]
print([list(x) for x in [(0, 3), (1, 4), (2, 5)]])
# [[0, 3], [1, 4], [2, 5]]
]]>The following details are described here.
set()
dict.fromkeys()
,sorted()
The same concept can be applied to tuples instead of lists.
See the following article for
Note that lists can store different types of data and are strictly different from arrays. If you want to handle arrays in processes that require memory size and memory addresses or numerical processing of large data, use array (standard library) or NumPy.
set()
If there is no need to preserve the order of the original list, use set(), which generates a set type set.
The set type is a data type that has no duplicate elements. When a list or other data type is passed to set(), duplicate values are ignored and an object of type set is returned in which only unique values are elements.
If you want to make it a tuple, use tuple().
l = [3, 3, 2, 1, 5, 1, 4, 2, 3]
print(set(l))
# {1, 2, 3, 4, 5}
print(list(set(l)))
# [1, 2, 3, 4, 5]
Of course, it can also be left as set. See the following article for more information on the set type set.
dict.fromkeys()
,sorted()
If you want to preserve the order of the original list, use the class method fromkeys() of the dictionary type or the built-in function sorted().
dict.fromkeys() creates a new dictionary object whose keys are lists, tuples, etc. specified in the arguments. If the second argument is omitted, the value is None.
Since dictionary keys do not have duplicate elements, duplicate values are ignored as in set(). In addition, a dictionary object can be passed as an argument to list() to obtain a list whose elements are dictionary keys.
print(dict.fromkeys(l))
# {3: None, 2: None, 1: None, 5: None, 4: None}
print(list(dict.fromkeys(l)))
# [3, 2, 1, 5, 4]
It has been guaranteed since Python 3.7 (CPython is 3.6) that dict.fromkeys() preserves the order of the argument sequence. Earlier versions use the built-in function sorted() as follows.
Specify the list tuple method index() for the argument key of sorted, which returns a sorted list of elements.
index() is a method that returns the index of the value (the number of the element in the list), which can be specified as the key of sorted() to sort the list based on the order of the original list. The argument key is specified as a callable (callable) object, so do not write ().
print(sorted(set(l), key=l.index))
# [3, 2, 1, 5, 4]
For two-dimensional arrays (lists of lists), the method using set() or dict.fromkeys() results in a TypeError.
l_2d = [[1, 1], [0, 1], [0, 1], [0, 0], [1, 0], [1, 1], [1, 1]]
# l_2d_unique = list(set(l_2d))
# TypeError: unhashable type: 'list'
# l_2d_unique_order = dict.fromkeys(l_2d)
# TypeError: unhashable type: 'list'
This is because non-hashable objects such as lists cannot be elements of type set or keys of type dict.
Define the following functions The order of the original list is preserved and works for one-dimensional lists and tuples.
def get_unique_list(seq):
seen = []
return [x for x in seq if x not in seen and not seen.append(x)]
print(get_unique_list(l_2d))
# [[1, 1], [0, 1], [0, 0], [1, 0]]
print(get_unique_list(l))
# [3, 2, 1, 5, 4]
List comprehension notation is used.
Here, we use the following
If the elements of the original list seq do not exist in the seen, then and after are evaluated.
seen.append(x) is executed and the element is added to seen.
Because the append() method returns None and None is False, not seen.append(x) evaluates to True.
The conditional expression in the list comprehension notation becomes True and is added as an element of the final generated list.
If the elements of the original list seq are present in seen, then x not in seen is False, and the conditional expression for the list comprehension expression is False.
Therefore, they are not added as elements of the final generated list.
Another method is to set the argument axis in NumPy's function np.unique(), although the result will be sorted.
To extract only duplicate elements from the original list, use collections.Counter().
Returns a collections.Counter (a subclass of dictionary) with the elements as keys and the number of elements as values.
import collections
l = [3, 3, 2, 1, 5, 1, 4, 2, 3]
print(collections.Counter(l))
# Counter({3: 3, 2: 2, 1: 2, 5: 1, 4: 1})
Since it is a subclass of dictionary, items() can be used to retrieve keys and values. It is sufficient to extract keys whose number is two or more.
print([k for k, v in collections.Counter(l).items() if v > 1])
# [3, 2, 1]
As shown in the example above, since Python 3.7, the keys of collections.Counter retain the order of the original list and so on.
In earlier versions, sorting with sorted() is sufficient, as is deleting duplicate elements.
print(sorted([k for k, v in collections.Counter(l).items() if v > 1], key=l.index))
# [3, 2, 1]
If you wish to extract duplicates as they are, simply leave elements from the original list with a number of two or more. The order is also preserved.
cc = collections.Counter(l)
print([x for x in l if cc[x] > 1])
# [3, 3, 2, 1, 1, 2, 3]
For two-dimensional arrays (lists of lists), the following functions are possible when the order of the original list is not retained and when it is retained, respectively. It also works for one-dimensional lists and tuples.
l_2d = [[1, 1], [0, 1], [0, 1], [0, 0], [1, 0], [1, 1], [1, 1]]
def get_duplicate_list(seq):
seen = []
return [x for x in seq if not seen.append(x) and seen.count(x) == 2]
def get_duplicate_list_order(seq):
seen = []
return [x for x in seq if seq.count(x) > 1 and not seen.append(x) and seen.count(x) == 1]
print(get_duplicate_list(l_2d))
# [[0, 1], [1, 1]]
print(get_duplicate_list_order(l_2d))
# [[1, 1], [0, 1]]
print(get_duplicate_list(l))
# [3, 1, 2]
print(get_duplicate_list_order(l))
# [3, 2, 1]
If you want to extract with duplicates, leave elements from the original list with a count of two or more.
print([x for x in l_2d if l_2d.count(x) > 1])
# [[1, 1], [0, 1], [0, 1], [1, 1], [1, 1]]
Note that since the computational complexity of count() is O(n), the function shown above that repeatedly executes count() is very inefficient. There may be a smarter way.
Counter is a subclass of dictionary, so if you pass a list or tuple whose elements are lists or other non-hashable objects to collections.Counter(), an error will occur and you will not be able to use it.
# print(collections.Counter(l_2d))
# TypeError: unhashable type: 'list'
]]>See the following article on how to remove or extract duplicate elements from a list.
Note that lists can store different types of data and are strictly different from arrays. If you want to handle arrays in processes that require memory size and memory addresses or numerical processing of large data, use array (standard library) or NumPy.
If the element does not have an updatable object such as a list, use the constructor set() of the set set type.
The set type is a data type that has no duplicate elements. When a list is passed to the constructor set(), duplicate values are ignored and an object of type set with only unique values as elements is returned.
The number of elements in this set type object and the original list are obtained and compared using the built-in function len().
Functions that return false if there are no duplicate elements and true if there are duplicate elements are as follows
def has_duplicates(seq):
return len(seq) != len(set(seq))
l = [0, 1, 2]
print(has_duplicates(l))
# False
l = [0, 1, 1, 2]
print(has_duplicates(l))
# True
The example is a list, but the same function can be used with tuples.
Mutable (updatable) objects such as lists cannot be elements of type set. Therefore, lists with lists as elements (two-dimensional arrays, lists of lists, etc.) will result in a TypeError. The countermeasure is shown below.
l_2d = [[0, 1], [1, 1], [0, 1], [1, 0]]
# print(has_duplicates(l_2d))
# TypeError: unhashable type: 'list'
In the case of a list with a list of elements (such as a list of lists), the following functions can be used to determine if there are duplicate elements.
def has_duplicates2(seq):
seen = []
unique_list = [x for x in seq if x not in seen and not seen.append(x)]
return len(seq) != len(unique_list)
l_2d = [[0, 0], [0, 1], [1, 1], [1, 0]]
print(has_duplicates2(l_2d))
# False
l_2d = [[0, 0], [0, 1], [1, 1], [1, 1]]
print(has_duplicates2(l_2d))
# True
Instead of set(), the list comprehension notation generates a list whose elements are only unique values, and the number of elements is compared. See the following article for details.
This function is also valid for lists that do not have a list of elements.
l = [0, 1, 2]
print(has_duplicates2(l))
# False
l = [0, 1, 1, 2]
print(has_duplicates2(l))
# True
The example so far is the determination of whether the list of elements is duplicated (contains the same list).
Whether the elements of each list overlap can be determined after flattening the original list to one dimension.
l_2d = [[0, 1], [2, 3]]
print(sum(l_2d, []))
# [0, 1, 2, 3]
print(has_duplicates(sum(l_2d, [])))
# False
l_2d = [[0, 1], [2, 0]]
print(has_duplicates(sum(l_2d, [])))
# True
Here, sum() is used to flatten the list, but itertools.chain.from_iterable() can also be used. In addition, when flattening a list of three or more dimensions, it is necessary to define a new function.
]]>The type set is a collection of non-duplicate elements (elements that are not the same value, unique elements) and can perform set operations such as union set, product set, and difference set.
In this section, basic operations in set-type set operations are explained with sample code.
{}
,set()
len()
add()
discard()
,remove()
,pop()
,clear()
union()
intersection()
difference()
symmetric_difference()
issubset()
issuperset()
isdisjoint()
The set type is a mutable type that can add and delete elements, and there is also a frozenset type that has the same set operation and other methods as the set type but is immutable (cannot be modified by adding, deleting, or otherwise modifying elements).
{}
, set()
Objects of type set can be created by enclosing elements in braces {}.
If there are duplicate values, they are ignored and only unique values remain as elements.
s = {1, 2, 2, 3, 1, 4}
print(s)
print(type(s))
# {1, 2, 3, 4}
# <class 'set'>
It is possible to have different types as elements. However, updatable objects such as list types cannot be registered. Tuples are allowed.
Also, since set types are unordered, the order in which they are generated is not stored.
s = {1.23, 'abc', (0, 1, 2), 'abc'}
print(s)
# {(0, 1, 2), 1.23, 'abc'}
# s = {[0, 1, 2]}
# TypeError: unhashable type: 'list'
Different types, such as int and float, are considered duplicates if their values are equivalent.
s = {100, 100.0}
print(s)
# {100}
Since an empty brace {} is considered a dictionary type, an empty set type object (empty set) can be created using the constructor described next.
s = {}
print(s)
print(type(s))
# {}
# <class 'dict'>
Objects of type set can also be created with the constructor set().
Specifying an iterable object such as a list or tuple as an argument generates a set object whose elements are unique values only, with duplicate elements excluded.
l = [1, 2, 2, 3, 1, 4]
print(l)
print(type(l))
# [1, 2, 2, 3, 1, 4]
# <class 'list'>
s_l = set(l)
print(s_l)
print(type(s_l))
# {1, 2, 3, 4}
# <class 'set'>
Immutable frozenset types are created with the constructor frozenset().
fs_l = frozenset(l)
print(fs_l)
print(type(fs_l))
# frozenset({1, 2, 3, 4})
# <class 'frozenset'>
If the argument is omitted, an empty set-type object (empty set) is created.
s = set()
print(s)
print(type(s))
# set()
# <class 'set'>
Duplicate elements can be removed from a list or tuple using set(), but the order of the original list is not preserved.
To convert a set type into a list or tuple, use list(),tuple().
l = [2, 2, 3, 1, 3, 4]
l_unique = list(set(l))
print(l_unique)
# [1, 2, 3, 4]
See the following article for information on removing duplicate elements while preserving order, extracting only duplicate elements, and processing duplicate elements in a two-dimensional array (list of lists).
As well as list comprehensions, there are set comprehensions. Simply replace the square brackets [] with braces {} in list comprehensions.
s = {i**2 for i in range(5)}
print(s)
# {0, 1, 4, 9, 16}
See the following article for more information on list comprehension notation.
len()
The number of elements in a set can be obtained with the built-in function len().
s = {1, 2, 2, 3, 1, 4}
print(s)
print(len(s))
# {1, 2, 3, 4}
# 4
If you want to count the number of elements in each list that has elements with duplicate values, etc., see the following article.
add()
To add an element to a set, use the add() method.
s = {0, 1, 2}
s.add(3)
print(s)
# {0, 1, 2, 3}
discard()
,remove()
,pop()
,clear()
To remove an element from a set, use the discard(), remove(), pop(), and clear() methods.
The discard() method deletes the element specified in the argument. If a value that does not exist in the set is specified, nothing is done.
s = {0, 1, 2}
s.discard(1)
print(s)
# {0, 2}
s = {0, 1, 2}
s.discard(10)
print(s)
# {0, 1, 2}
The remove() method also removes the element specified in the argument, but an error KeyError is returned if a value that does not exist in the set is specified.
s = {0, 1, 2}
s.remove(1)
print(s)
# {0, 2}
# s = {0, 1, 2}
# s.remove(10)
# KeyError: 10
The pop() method removes elements from a set and returns their values. It is not possible to select which values to remove. An empty set will result in a KeyError error.
s = {2, 1, 0}
v = s.pop()
print(s)
print(v)
# {1, 2}
# 0
s = {2, 1, 0}
print(s.pop())
# 0
print(s.pop())
# 1
print(s.pop())
# 2
# print(s.pop())
# KeyError: 'pop from an empty set'
The clear() method removes all elements and makes the set empty.
s = {0, 1, 2}
s.clear()
print(s)
# set()
union()
The union set (merger, union) can be obtained with the | operator or the union() method.
s1 = {0, 1, 2}
s2 = {1, 2, 3}
s3 = {2, 3, 4}
s_union = s1 | s2
print(s_union)
# {0, 1, 2, 3}
s_union = s1.union(s2)
print(s_union)
# {0, 1, 2, 3}
Multiple arguments can be specified for a method. In addition to the set type, lists and tuples that can be converted to the set type by set() can also be specified as arguments. The same applies to subsequent operators and methods.
s_union = s1.union(s2, s3)
print(s_union)
# {0, 1, 2, 3, 4}
s_union = s1.union(s2, [5, 6, 5, 7, 5])
print(s_union)
# {0, 1, 2, 3, 5, 6, 7}
intersection()
The product set (common part, intersection, and intersection) can be obtained with the & operator or the intersection() method.
s_intersection = s1 & s2
print(s_intersection)
# {1, 2}
s_intersection = s1.intersection(s2)
print(s_intersection)
# {1, 2}
s_intersection = s1.intersection(s2, s3)
print(s_intersection)
# {2}
difference()
The difference set can be obtained with the – operator or the difference() method.
s_difference = s1 - s2
print(s_difference)
# {0}
s_difference = s1.difference(s2)
print(s_difference)
# {0}
s_difference = s1.difference(s2, s3)
print(s_difference)
# {0}
symmetric_difference()
The symmetric difference set (the set of elements contained in only one of the two) can be obtained with the ^ operator or symmetric_difference().
Equivalent to exclusive disjunction (XOR) in logical operations.
s_symmetric_difference = s1 ^ s2
print(s_symmetric_difference)
# {0, 3}
s_symmetric_difference = s1.symmetric_difference(s2)
print(s_symmetric_difference)
# {0, 3}
issubset()
To determine whether a set is a subset of another set, use the <= operator or the issubset() method.
s1 = {0, 1}
s2 = {0, 1, 2, 3}
print(s1 <= s2)
# True
print(s1.issubset(s2))
# True
Both the <= operator and the issubset() method return true for equivalent sets.
To determine if it is a true subset, use the <= operator, which returns false for equivalent sets.
print(s1 <= s1)
# True
print(s1.issubset(s1))
# True
print(s1 < s1)
# False
issuperset()
To determine if one set is a superset of another, use the >= operator or issuperset().
s1 = {0, 1}
s2 = {0, 1, 2, 3}
print(s2 >= s1)
# True
print(s2.issuperset(s1))
# True
Both the >= operator and the issuperset() method return true for equivalent sets.
To determine if it is a true superset, use the >= operator, which returns false for equivalent sets.
print(s1 >= s1)
# True
print(s1.issuperset(s1))
# True
print(s1 > s1)
# False
isdisjoint()
To determine if two sets are prime to each other, use the isdisjoint() method.
s1 = {0, 1}
s2 = {1, 2}
s3 = {2, 3}
print(s1.isdisjoint(s2))
# False
print(s1.isdisjoint(s3))
# True
]]>The following contents are explained here, along with sample code.
type()
type()
, isinstance()
Instead of determining the type of an object, one can use exception handling or the built-in function hasattr() to determine whether an object has the correct methods and attributes.
type(object) is a function that returns the type of the object passed as argument. This can be used to find out the type of an object.
print(type('string'))
# <class 'str'>
print(type(100))
# <class 'int'>
print(type([0, 1, 2]))
# <class 'list'>
The return value of type() is a type object such as str or int.
print(type(type('string')))
# <class 'type'>
print(type(str))
# <class 'type'>
type()
, isinstance()
Use type() or isinstance() to determine the type.
By comparing the return value of type() with an arbitrary type, it can be determined if the object is of any type.
print(type('string') is str)
# True
print(type('string') is int)
# False
def is_str(v):
return type(v) is str
print(is_str('string'))
# True
print(is_str(100))
# False
print(is_str([0, 1, 2]))
# False
If you want to determine if it is one of several types, use the in operator and a tuple or list of several types.
def is_str_or_int(v):
return type(v) in (str, int)
print(is_str_or_int('string'))
# True
print(is_str_or_int(100))
# True
print(is_str_or_int([0, 1, 2]))
# False
It is also possible to define functions that change processing depending on the argument type.
def type_condition(v):
if type(v) is str:
print('type is str')
elif type(v) is int:
print('type is int')
else:
print('type is not str or int')
type_condition('string')
# type is str
type_condition(100)
# type is int
type_condition([0, 1, 2])
# type is not str or int
isinstance(object, class) is a function that returns true if the object of the first argument is an instance of the type or subclass of the second argument.
The second argument can be a tuple of types. If it is an instance of either type, true is returned.
print(isinstance('string', str))
# True
print(isinstance(100, str))
# False
print(isinstance(100, (int, str)))
# True
A function similar to the example of type determination using type() can be written as follows
def is_str(v):
return isinstance(v, str)
print(is_str('string'))
# True
print(is_str(100))
# False
print(is_str([0, 1, 2]))
# False
def is_str_or_int(v):
return isinstance(v, (int, str))
print(is_str_or_int('string'))
# True
print(is_str_or_int(100))
# True
print(is_str_or_int([0, 1, 2]))
# False
def type_condition(v):
if isinstance(v, str):
print('type is str')
elif isinstance(v, int):
print('type is int')
else:
print('type is not str or int')
type_condition('string')
# type is str
type_condition(100)
# type is int
type_condition([0, 1, 2])
# type is not str or int
The difference between type() and isinstance() is that isinstance() returns true for instances of subclasses that inherit the class specified as the second argument.
For example, the following superclass (base class) and subclass (derived class) are defined
class Base:
pass
class Derive(Base):
pass
base = Base()
print(type(base))
# <class '__main__.Base'>
derive = Derive()
print(type(derive))
# <class '__main__.Derive'>
Type determination using type() returns true only when the types match, but isinstance() returns true even for superclasses.
print(type(derive) is Derive)
# True
print(type(derive) is Base)
# False
print(isinstance(derive, Derive))
# True
print(isinstance(derive, Base))
# True
Even for standard types, for example, the boolean type bool (true,false), care must be taken. bool is a subclass of integer type, so isinstance() returns true even for an int from which it is inherited.
print(type(True))
# <class 'bool'>
print(type(True) is bool)
# True
print(type(True) is int)
# False
print(isinstance(True, bool))
# True
print(isinstance(True, int))
# True
If you want to determine the exact type, use type(); if you want to determine the type with inheritance taken into account, use isinstance().
The built-in function issubclass() is also provided to determine whether a class is a subclass of another class.
print(issubclass(bool, int))
# True
print(issubclass(bool, float))
# False
]]>