Type Checker
Problem Statement
Identify the types of different Python values.
Background
Python has several built-in types:
- int - integers (1, 42, -5)
- float - floating point numbers (3.14, 2.0)
- str - strings ("hello", 'world')
- bool - booleans (True, False)
- list - ordered collections ([1, 2, 3])
- dict - key-value mappings ({"a": 1})
Your Task
Write a function get_types(values) that takes a list of values and returns a list of their type names as strings.
Output Format
Return a list of type names (e.g., ["int", "str", "float"]).
Example:
[42, 'hello', 3.14, True, [1,2], {'a': 1}]['int', 'str', 'float', 'bool', 'list', 'dict']
type(42).name returns 'int', type('hello').name returns 'str', etc.
Constraints:
- Use type() function
- Return type name as string using name
Background Knowledge
Python is a dynamically typed language, meaning variables don't require explicit type declarations—the interpreter determines types at runtime. The core built-in types include int (whole numbers like 42), float (decimals like 3.14), str (text like "hello"), bool (True/False), list (mutable sequences like [1, 2]), and dict (key-value pairs like {"a": 1}). Understanding these is fundamental for type checking, as it ensures code handles data correctly without runtime errors from type mismatches.
The type() function returns a value's type object (e.g., <class 'int'>), which can be converted to a string via type(value).name. This introspection capability is key for runtime type analysis, common in validation, debugging, and data processing tasks. Lists, being iterable containers, allow batch processing of mixed-type values.
Algorithm/Approach
Iterate and map: Traverse the input list, apply type introspection to each element, extract the lowercase type name, and collect results in a new list. This is a classic "map" pattern over iterables, leveraging Python's functional tools like list comprehensions for conciseness.
Step-by-Step Strategy
- Define the function signature: Accept a list parameter (e.g., values: list for clarity, though optional).
- Initialize result list: Create an empty list to store type strings.
- Loop or comprehend over input: For each value, use type(value).name to get the type name as a string.
- Append/extract: Add each type name to the result list (handles all listed types automatically).
- Return the result: Output the list in the exact order of input values.
Example skeleton (conceptual):
def get_types(values):
result = []
for value in values:
# Extract type name here
pass
return result
Common Pitfalls
- Nested types: type() checks the immediate container (e.g., type([1,2]) → "list"), not contents—don't recurse unless specified.
- NoneType: None yields "NoneType"; confirm if problem expects it or assumes no None.
- Custom objects: Focus on built-ins; user-defined classes return their class name.
- Mutability confusion: list vs. tuple—type((1,2)) → "tuple", not listed here.
- String casing: Use name for lowercase ("int", not "IntType").
- Empty containers: type([]) → "list"; type({}) → "dict" (empty dict, not set).
Time & Space Complexity
- Time: O(n), where n is list length—single pass with constant-time type() calls.
- Space: O(n) for output list; no extra scaling beyond input size. Efficient for large lists due to Python's optimized iteration.