Skip to main content

Python Fundamentals for Data Engineering Interviews


Build a strong Python foundation with practical examples for data engineering work. Learn to manipulate data structures, control program flow, write reusable functions, handle errors, and process files and JSON payloads.

What you'll learn: Variables and operators, core collections, loops and conditionals, functions and comprehensions, exception handling, file handling, and JSON processing.

1. Variables, Data Types, and Operators

Variables are names that refer to objects. Python is dynamically typed, so you don't declare a variable's type in advance. The type belongs to the object, and a variable can later refer to an object of another type.

name = "Asha"          # str
age = 29               # int
salary = 85000.50      # float
is_engineer = True     # bool
middle_name = None     # NoneType

print(type(name))      # <class 'str'>
print(type(age))       # <class 'int'>

Common data types

TypeExampleTypical use
int42Counts, IDs where numeric arithmetic is intended
float3.14Approximate numeric values
str"data"Text
boolTrueLogical conditions
NoneTypeNoneMissing or absent value

Operators

# Arithmetic
print(10 + 3)   # 13
print(10 / 3)   # 3.333...
print(10 // 3)  # 3: floor division
print(10 % 3)   # 1: remainder
print(2 ** 3)   # 8: exponentiation

# Comparison and logical operators
print(5 > 3)                    # True
print(5 == 5 and 2 < 4)        # True
print(not False)                # True

# Membership and identity
print("py" in "python")         # True
x = None
print(x is None)                # True
Interview tip: Use == to compare values and is to test object identity. For checking a missing value, value is None is the standard pattern.

Type conversion

count = int("25")
price = float("19.99")
code = str(1234)
enabled = bool(1)

# Be careful: bool("False") is True because
# every non-empty string is truthy.
print(bool(""))       # False
print(bool("False")) # True

2. Lists, Tuples, Sets, and Dictionaries

Python collections store multiple values, but differ in ordering, mutability, and uniqueness.

CollectionOrdered?Mutable?Duplicates?Typical use
List []YesYesYesSequence of records or values
Tuple ()YesNoYesFixed group of values
Set {...}No guaranteed iteration orderYesNoUnique values and membership tests
Dictionary {key: value}Insertion-orderedYesKeys must be uniqueLookups by key

Lists

numbers = [10, 20, 30, 20]
numbers.append(40)
numbers[0] = 5

print(numbers)       # [5, 20, 30, 20, 40]
print(numbers[1:3])  # [20, 30]
print(numbers[-1])   # 40

Tuples

coordinates = (12.9, 77.6)
latitude, longitude = coordinates
print(latitude, longitude)

# A one-element tuple needs a trailing comma
single_item = (42,)

Sets

source_a = {"A", "B", "C"}
source_b = {"B", "C", "D"}

print(source_a | source_b)  # union
print(source_a & source_b)  # intersection
print(source_a - source_b)  # values only in source_a

unique_ids = set([101, 102, 101, 103])
print(unique_ids)            # {101, 102, 103}

Dictionaries

customer = {
    "customer_id": 101,
    "name": "Asha",
    "country": "India"
}

print(customer["name"])
print(customer.get("email"))  # None if key is absent
customer["active"] = True

for key, value in customer.items():
    print(key, value)
Common pitfall: customer["email"] raises KeyError if the key is absent, while customer.get("email") returns None by default. Use a distinct default if a missing key must be distinguished from a stored None.

3. Loops and Conditional Statements

Use if, elif, and else to branch, and use for or while loops to repeat work.

row_count = 120

if row_count == 0:
    status = "empty"
elif row_count < 100:
    status = "small"
else:
    status = "large"

print(status)  # large

For loops and enumerate

tables = ["customers", "orders", "products"]

for table in tables:
    print(f"Processing {table}")

for index, table in enumerate(tables, start=1):
    print(index, table)

While loops and control flow

retries = 0
max_retries = 3

while retries < max_retries:
    print("Attempt", retries + 1)
    retries += 1

for number in range(1, 6):
    if number == 3:
        continue  # skip this iteration
    if number == 5:
        break     # stop the loop
    print(number)
Data engineering example: Iterate over a list of files or partitions to process each batch. In production, also capture per-file failures and ensure retrying a batch won't duplicate its output.

4. Functions, Lambda, and Comprehensions

Functions package reusable logic and make code easier to test. Prefer explicit parameters and return values over hidden side effects.

Defining functions

def calculate_net_amount(amount, discount=0):
    """Return the amount after applying a discount."""
    return amount - discount

print(calculate_net_amount(100, 15))  # 85
print(calculate_net_amount(100))      # 100

Positional and keyword arguments

def describe_job(name, region="asia-south1"):
    return f"{name} runs in {region}"

print(describe_job("daily_orders"))
print(describe_job(name="customer_load", region="europe-west3"))

Lambda functions

A lambda is a small anonymous function, useful for short expressions passed to other functions.

records = [
    {"name": "Asha", "amount": 120},
    {"name": "Ravi", "amount": 90},
    {"name": "Mina", "amount": 150}
]

sorted_records = sorted(records, key=lambda row: row["amount"])
print(sorted_records)

List, set, and dictionary comprehensions

values = [1, 2, 3, 4, 5, 6]

squares = [x * x for x in values]
evens = [x for x in values if x % 2 == 0]
unique_lengths = {len(name) for name in ["sql", "python", "beam"]}
lookup = {x: x * x for x in values}

print(squares)
print(evens)
print(lookup)
Keep comprehensions readable: Use them for straightforward transformations and filters. If the logic has several branches or side effects, a regular loop or named function is usually easier to maintain.

Generator expressions

# Generates values lazily instead of building a full list.
total = sum(int(value) for value in ["10", "20", "30"])
print(total)  # 60

A generator expression can reduce memory use for large inputs, but it is usually consumed only once.

5. Exception Handling

Exceptions represent errors or unusual conditions. Handle errors you can recover from, add useful context, and avoid silently swallowing failures.

raw_value = "not-a-number"

try:
    value = int(raw_value)
except ValueError as exc:
    print(f"Invalid integer: {raw_value!r}")
    # In a real pipeline, log context or route the row
else:
    print("Parsed:", value)
finally:
    print("Parsing attempt finished")
  • try: code that may raise an exception.
  • except: handles a matching exception type.
  • else: runs only if the try block completes without an exception.
  • finally: runs whether or not an exception occurred, commonly for cleanup.

Raise a meaningful exception

def validate_amount(amount):
    if amount < 0:
        raise ValueError("amount must not be negative")
    return amount

try:
    validate_amount(-10)
except ValueError as exc:
    print("Validation failed:", exc)
Interview tip: Catch specific exceptions such as ValueError, KeyError, or FileNotFoundError. Avoid a bare except: because it can hide programming errors and interrupts.

6. File Handling and JSON Processing

Use with open(...) so files are closed automatically, including when an exception occurs. Specify an encoding when working with text files.

Read and write text files

# Read an entire text file
with open("input.txt", "r", encoding="utf-8") as file:
    content = file.read()

# Read a large file line by line
with open("events.log", "r", encoding="utf-8") as file:
    for line in file:
        line = line.rstrip("\\n")
        if line:
            print(line)

# Write a text file (overwrites existing contents)
with open("output.txt", "w", encoding="utf-8") as file:
    file.write("Pipeline completed\\n")

Process JSON

JSON is commonly used for API responses, configuration files, and event payloads. Python's built-in json module converts between JSON text and Python objects.

import json

payload = {
    "event_id": 501,
    "event_type": "order_created",
    "amount": 1299.50,
    "tags": ["web", "priority"]
}

# Python object -> JSON string
json_text = json.dumps(payload, indent=2)
print(json_text)

# JSON string -> Python object
parsed = json.loads(json_text)
print(parsed["event_type"])
print(parsed["tags"][0])

Read and write JSON files

import json

# Read a JSON document
with open("config.json", "r", encoding="utf-8") as file:
    config = json.load(file)

# Write a JSON document
with open("result.json", "w", encoding="utf-8") as file:
    json.dump(config, file, indent=2)
JSON versus JSON Lines (JSONL): A JSON document contains one JSON value, while JSONL stores one JSON value per line. For large event files, process JSONL one line at a time rather than loading the entire file into memory.

Process a JSONL file safely

import json

with open("events.jsonl", "r", encoding="utf-8") as file:
    for line_number, line in enumerate(file, start=1):
        if not line.strip():
            continue
        try:
            event = json.loads(line)
        except json.JSONDecodeError as exc:
            print(f"Bad JSON on line {line_number}: {exc}")
            continue

        event_id = event.get("event_id")
        print(event_id)

In production, malformed records should be logged with enough context and sent to a quarantine or dead-letter path when required. Don't log secrets or sensitive payload fields.

Interview Questions to Practice

1. What is the difference between a list and a tuple?

Both preserve order and allow duplicates, but lists are mutable while tuples are immutable. Use lists for collections that change and tuples for fixed groupings of values.

2. What is the difference between a set and a dictionary?

A set stores unique elements. A dictionary maps unique, hashable keys to values and preserves insertion order in modern Python.

3. What is the difference between == and is?

== checks value equality. is checks whether two references point to the same object. Use is None to test for None.

4. When would you use a lambda or a comprehension?

A lambda is useful for a short function expression, such as a sorting key. Comprehensions concisely build collections from an iterable. Use named functions or regular loops when the logic becomes complex.

5. Why use a context manager for file handling?

The with statement ensures the file is closed when the block exits, including when an exception occurs. It makes resource handling safer and clearer.

6. What is the difference between json.load and json.loads?

json.load(file) reads JSON from a file-like object. json.loads(text) parses a JSON string.

7. How would you process a very large JSONL file?

Read it line by line, parse each non-empty line, validate its structure, and write results incrementally. Add malformed-record handling, observability, and retry-safe output rather than loading the entire file into memory.

Chapter Summary

  • Python variables reference dynamically typed objects; understand common data types and truthiness.
  • Choose lists, tuples, sets, and dictionaries based on ordering, mutability, uniqueness, and lookup needs.
  • Use loops and conditionals to control processing flow.
  • Write reusable functions; use lambdas and comprehensions for small, clear transformations.
  • Handle expected exceptions specifically and preserve useful debugging context.
  • Use context managers for files and the json module for JSON data; stream JSONL records for large files.
Practice challenge: Read a JSONL file containing order events, skip blank lines, handle malformed JSON, validate required fields, remove duplicate event IDs, and write valid records to a new JSONL file. Explain how you'd make the pipeline observable and safe to rerun.

Note: Examples use Python 3. Adapt file paths, validation rules, logging, and error handling to your runtime and production requirements.

Comments

Popular posts from this blog

Tricky Questions or Puzzles in C ( Updated for 2026)

Updated for 2026 This article was originally written when C/C++ puzzles were commonly asked in interviews. While such language-specific puzzles are less frequent today, the problem-solving and logical reasoning skills tested here remain highly relevant for modern Software Engineering, Data Engineering, SQL, and system design interviews . Why These Puzzles Still Matter in 2026 Although most Software &   Data Engineering interviews today focus on Programming, SQL, data pipelines, cloud platforms, and system design , interviewers still care deeply about how you think . These puzzles test: Logical reasoning Edge-case handling Understanding of execution flow Ability to reason under pressure The language may change , but the thinking patterns do not . How These Skills Apply to Data Engineering Interviews The same skills tested by C/C++ puzzles appear in modern interviews as: SQL edge cases and NULL handling Data pipeline failure scenarios Incremental vs ...

Programs and Puzzles in technical interviews i faced

I have attended interview of nearly 10 companies in my campus placements and sharing their experiences with you,though i did not got selected in any of the companies but i had great experience facing their interviews and it might help you as well in preparation of interviews.Here are some of the puzzles and programs asked to me in interview in some of the good companies. 1) SAP Labs I attended sap lab online test in my college through campus placements.It had 3 sections,the first one is usual aptitude questions which i would say were little tricky to solve.The second section was Programming test in which you were provided snippet of code and you have to complete the code (See Tricky Code Snippets  ).The code are from different data structures like Binary Tree, AVL Tree etc.Then the third section had questions from Database,OS and Networks.After 2-3 hours we got the result and i was shortlisted for the nest round of interviews scheduled next day.Then the next day we had PPT of t...

Decorators in Python

Decorators provide additional functionality to the functions without directly changing their definition of them. Basically, it takes the functions as an argument, adds functionality to them, and returns it.  Before diving deep into the concept of Decorators, let's first try to understand  What are functions in Python and what is an inner function? In Python everything is Objects, be it Class, Variables, and Functions . So functions are python first-class objects that can be used or passed as an argument. You can store the functions in variables, you can pass a function to another function as parameters, and you can also return the function from the function. Below is one simple example where we are treating functions as objects . def make_me_lowercase ( str ): return str .lower() print (make_me_lowercase( "HELLO World" )) copy_of_you = make_me_lowercase print (copy_of_you( "HELLO World" )) The output of the above calls for both the functio...