For Python integers, n % 2 != 0 checks oddness. Decide explicitly whether booleans and integer subclasses belong in your input contract.
For a Python integer, n % 2 != 0 tells you whether it is odd. Python integers can grow beyond a machine word, so the same expression works for a small counter or a very large exact value. A public helper should also say which input types it accepts.
A strict integer helper
def is_odd(n: int) -> bool:
if type(n) is not int:
raise TypeError('Expected a built-in int')
return n % 2 != 0
assert is_odd(35)
assert is_odd(-35)
assert not is_odd(-34)
assert not is_odd(0)
assert is_odd(10**80 + 1)
Choose a policy for booleans and subclasses
This version deliberately accepts only the built-in int type. It rejects booleans, floats, strings, and integer subclasses. That strict choice is useful at a boundary where True should not stand in for the number one. Python documents that bool is a subclass of int, which is why isinstance(True, int) alone is not enough for this contract.
If your application should accept integer subclasses, use isinstance(n, int) and not isinstance(n, bool) instead. That policy is broader than the example above. Choose one intentionally and cover it with a test; silently accepting extra types makes a tiny helper more surprising than its arithmetic.
Understand negative remainders and input types
With a positive divisor of two, Python's remainder is nonnegative. Thus -35 % 2 is 1. The language reference describes the divisor-sign rule. Comparing with zero remains a clear way to express divisibility and is easy to recognize when translating the function to another language.
Type annotations do not enforce this input rule while the program runs. Calling is_odd(3.5) still reaches the function, where the explicit check raises the exception. An unguarded modulo expression would return a nonzero remainder for that fraction, but parity is a property of integers.
When values arrive as text, validate and parse them before invoking the helper. A command-line program might deliberately accept surrounding whitespace through int(text). A file format might require a much narrower decimal grammar. Keep the parsing policy visible rather than having a boolean predicate reinterpret every string it receives.
Filter and test integer collections
For a collection already known to contain integers, filtering is straightforward:
counts = [-8, -7, 0, 4, 11]
odd_counts = [n for n in counts if is_odd(n)]
assert odd_counts == [-7, 11]
Include zero, a negative odd value, and a rejected boolean in your checks. Add a large integer if the data pipeline handles large identifiers, and ensure that pipeline never converts the value through a floating-point number first. Exact arithmetic cannot recover digits lost during an earlier conversion. There is no need for a remote service to answer this question.