15 Python Array and String Practice Problems for Beginners: Master the Basics

What Are Python Arrays and Strings?

In Python, what we traditionally call an “array” in other languages like C or Java is most commonly implemented as a list. Python lists are highly flexible, dynamic arrays that can hold elements of different data types. For strict, fixed-type arrays, Python offers an array module, but for 95% of beginner practice problems and coding interviews, lists are the standard.

A string is simply a sequence of characters enclosed in single, double, or triple quotes. Unlike lists, strings in Python are immutable. This means once you create a string, you cannot modify its characters in place; you must create a new string altogether.


Why People Focus on Array and String Practice Problems

When companies like Infosys, Cognizant, or startups recruit freshers, they rarely test you on complex machine learning models right away. Instead, they want to see if you can manipulate basic data streams.

If you look at how real-world data moves, it is almost always structured as collections (arrays) or text logs (strings). A backend developer working on an e-commerce platform spends a lot of time sorting lists of product prices or formatting user-submitted address fields. Practicing these problems trains your brain to think sequentially and structurally.


Key Features of Python’s Sequence Types

Python makes working with sequences incredibly intuitive compared to lower-level languages. Here are the core built-in features you will leverage in these practice problems:

  • Negative Indexing: Access elements from the end of the collection using negative integers (e.g., my_list[-1] gets the last item).
  • Slicing syntax: Extract sub-sections easily using sequence[start:stop:step].
  • Dynamic Resizing: Python lists grow and shrink automatically; you do not need to declare a fixed size beforehand.
  • Rich Built-in Ecosystem: Methods like .append(), .pop(), .split(), and .join() handle heavy lifting out of the box.

How Code Execution Works Behind the Scenes

When you modify a list or string, Python handles memory management automatically. However, understanding the operational cost is critical.

When you insert an element at the beginning of a large Python list, Python has to shift every single subsequent element down by one slot in memory. This is an $O(n)$ operation. Conversely, appending an element to the end of a list is fast and efficient, running in $O(1)$ constant time.


Practical Use Cases

  • Data Cleaning: Removing duplicate entries from user signup sheets.
  • Text Processing: Scanning server error logs for specific keywords like “404” or “Timeout”.
  • Financial Math: Calculating the running balance or identifying the highest transaction value in a bank statement array.
  • Web Scraping: Extracting names, prices, or clean text strings from messy HTML pages.

Step-by-Step Guide: 15 Beginner Practice Problems

Section 1: Beginner Array (List) Problems

1. Find the Largest Element in an Array

Problem: Given a list of numbers, find the maximum value without using the built-in max() function.

def find_largest(nums):
    if not nums:
        return None
    largest = nums[0]
    for num in nums:
        if num > largest:
            largest = num
    return largest

# Example Usage
print(find_largest([12, 45, 2, 89, 23]))  # Output: 89

Explanation: We initialize largest with the first element and loop through the list. If we find a larger number, we update our variable. This helps you understand fundamental loop mechanics.

2. Reverse a List In-Place

Problem: Reverse the order of elements in a list without creating a new list.

def reverse_list(arr):
    left = 0
    right = len(arr) - 1
    while left < right:
        arr[left], arr[right] = arr[right], arr[left]
        left += 1
        right -= 1
    return arr

# Example Usage
print(reverse_list([1, 2, 3, 4, 5]))  # Output: [5, 4, 3, 2, 1]

Explanation: This uses the classic two-pointer approach. We swap the elements at the left and right indices, moving them closer together until they meet in the middle.

3. Count Occurrences of an Element

Problem: Count how many times a target element appears in a list.

def count_occurrences(arr, target):
    count = 0
    for item in arr:
        if item == target:
            count += 1
    return count

# Example Usage
print(count_occurrences([1, 2, 3, 2, 4, 2], 2))  # Output: 3

Observation: While Python has a built-in arr.count(target) method, writing this out manually builds a strong mental model for conditional execution within loops.

4. Remove Duplicates from a List

Problem: Remove duplicate elements from a list while maintaining the original order.

def remove_duplicates(arr):
    seen = []
    for item in arr:
        if item not in seen:
            seen.append(item)
    return seen

# Example Usage
print(remove_duplicates([1, 2, 2, 3, 4, 4, 5]))  # Output: [1, 2, 3, 4, 5]

Limitation Note: Using item not in seen on a standard list takes $O(n)$ time per look-up, making the overall process $O(n^2)$. For very large datasets, using a Python set is much faster because set lookups take $O(1)$ constant time.

5. Find the Missing Number

Problem: You are given a list containing integers from 1 to $n$, but one number is missing. Find it.

def find_missing_number(arr, n):
    expected_sum = n * (n + 1) // 2
    actual_sum = sum(arr)
    return expected_sum - actual_sum

# Example Usage
print(find_missing_number([1, 2, 4, 5, 6], 6))  # Output: 3

Explanation: This problem uses simple math instead of brute-force checking. We calculate the sum of the first $n$ natural numbers using the formula $\frac{n(n+1)}{2}$ and subtract the sum of our list elements from it.

6. Move All Zeros to the End

Problem: Move all zeros in a list to the end without changing the relative order of non-zero elements.

def move_zeros(arr):
    insert_pos = 0
    for i in range(len(arr)):
        if arr[i] != 0:
            arr[insert_pos] = arr[i]
            insert_pos += 1

    for i in range(insert_pos, len(arr)):
        arr[i] = 0
    return arr

# Example Usage
print(move_zeros([0, 1, 0, 3, 12]))  # Output: [1, 3, 12, 0, 0]

7. Find the Second Largest Element

Problem: Find the second largest distinct value in an array.

def second_largest(arr):
    if len(arr) < 2:
        return None
    first = second = float('-inf')
    for num in arr:
        if num > first:
            second = first
            first = num
        elif num > second and num != first:
            second = num
    return second if second != float('-inf') else None

# Example Usage
print(second_largest([10, 20, 4, 45, 45, 99]))  # Output: 45

Section 2: Beginner String Problems

8. Check for Palindrome

Problem: Determine if a string reads the same backward as forward, ignoring case.

def is_palindrome(s):
    cleaned = s.lower()
    return cleaned == cleaned[::-1]

# Example Usage
print(is_palindrome("Radar"))  # Output: True
print(is_palindrome("hello"))  # Output: False

Explanation: Here, we use Python’s slice step syntax [::-1] to quickly reverse the string. If the reversed version matches the original string, it’s a palindrome.

9. Count Vowels and Consonants

Problem: Count the total number of vowels and consonants in a text string.

def count_vowels_consonants(s):
    vowels = "aeiou"
    v_count = 0
    c_count = 0
    for char in s.lower():
        if char.isalpha():
            if char in vowels:
                v_count += 1
            else:
                c_count += 1
    return {"Vowels": v_count, "Consonants": c_count}

# Example Usage
print(count_vowels_consonants("Hello World!"))  # Output: {'Vowels': 3, 'Consonants': 7}

10. Reverse Words in a Sentence

Problem: Given a string of words separated by spaces, reverse the sequence of words.

def reverse_words(sentence):
    words = sentence.split()
    reversed_words = words[::-1]
    return " ".join(reversed_words)

# Example Usage
print(reverse_words("Python is awesome"))  # Output: "awesome is Python"

Scenario: This pattern is highly practical. For instance, when cleaning text parsed from PDF data tables, you frequently need to break sentences down into lists of words, filter them, and reassemble them.

11. Find the First Non-Repeated Character

Problem: Locate the first character in a string that does not repeat anywhere else.

def first_unique_char(s):
    char_counts = {}
    for char in s:
        char_counts[char] = char_counts.get(char, 0) + 1

    for char in s:
        if char_counts[char] == 1:
            return char
    return None

# Example Usage
print(first_unique_char("swiss"))  # Output: 'w'

12. Check for Anagrams

Problem: Check if two strings contain the exact same characters in different configurations.

def is_anagram(s1, s2):
    return sorted(s1.replace(" ", "").lower()) == sorted(s2.replace(" ", "").lower())

# Example Usage
print(is_anagram("Listen", "Silent"))  # Output: True

13. String Compression

Problem: Perform basic string compression using character counts (e.g., “aabcccccaaa” becomes “a2b1c5a3”).

def compress_string(s):
    if not s:
        return ""
    compressed = []
    count = 1
    for i in range(1, len(s)):
        if s[i] == s[i-1]:
            count += 1
        else:
            compressed.append(s[i-1] + str(count))
            count = 1
    compressed.append(s[-1] + str(count))
    result = "".join(compressed)
    return result if len(result) < len(s) else s

# Example Usage
print(compress_string("aabcccccaaa"))  # Output: "a2b1c5a3"

14. Extract Numbers from a String

Problem: Extract all numeric digits from a mixed alphanumeric string and return them as a clean integer.

def extract_digits(s):
    digits = [char for char in s if char.isdigit()]
    return int("".join(digits)) if digits else 0

# Example Usage
print(extract_digits("order_id_4829_processed"))  # Output: 4829

15. Substring Search Check

Problem: Check if a substring exists within a target string without using the built-in in keyword.

def contains_substring(main_str, sub_str):
    if not sub_str:
        return True
    for i in range(len(main_str) - len(sub_str) + 1):
        if main_str[i:i+len(sub_str)] == sub_str:
            return True
    return False

# Example Usage
print(contains_substring("development", "lop"))  # Output: True

Benefits of Practicing These Problems

  • Syntax Fluidity: You will stop mixing up brackets and stop forgetting colon placements.
  • Debugging Muscle Memory: You learn how to read errors like IndexError: list index out of range and fix them quickly.
  • Logical Deconstruction: You gain the ability to take large, complex prompts and break them down into smaller execution steps.

Limitations to Keep in Mind

While practicing array and string puzzles builds foundational skills, it has its limits. Relying solely on these isolated problems can give you a false sense of security.

Writing a clean 10-line loop function is very different from managing database migrations, designing API endpoints, or structuring large object-oriented systems. Real-world applications require you to manage architectural dependencies and external libraries, which these isolated code challenges don’t teach.

Pros and Cons of Python for Sequence Manipulation

ProsCons
Dynamic resizing saves you from manual memory allocations.Immutable strings can create heavy memory footprints when modified frequently inside large loops.
Incredibly readable syntax allows you to focus on logic rather than boilerplate code.Python is an interpreted language, making it slower than compiled options like C++ for heavy raw matrix operations.
Built-in slicing features reduce your code length dramatically.Automated features can mask how underlying algorithms work, making it easy to accidentally write slow code.

Common Mistakes Users Make

  • Modifying a list while looping through it: Removing elements from a list while iterating over it shifts the indices of subsequent items. This causes the loop to skip items or throw errors.
  • Forgetting string immutability: Trying to run code like my_string[0] = 'H' will throw a TypeError. You always need to reconstruct the string or convert it to a list first.
  • Confusing assignment with copying: Writing list_b = list_a does not create a new list. It creates a reference pointing to the same location in memory. Modifying list_b changes list_a too. Use list_b = list_a.copy() instead.

Frequently Asked Questions

1. What is the difference between a list and an array in Python?

A standard Python list can hold items of different data types and expands dynamically. A true Python array (from the array module) requires all items to be of the exact same data type, making it more memory efficient for large numeric datasets.

2. Why does Python give an IndexError in loops?

This happens when you try to access an index location that does not exist. It usually occurs if your loop counter runs up to len(array) instead of stopping at len(array) - 1 when handling zero-based indexing.

3. How do I reverse a string quickly without using a loop?

You can use Python’s built-in string slicing step feature: reversed_str = original_str[::-1].

4. What does the .join() method do?

The .join() method merges a list of individual strings into a single cohesive string, using a specified separator string between each element.

5. Why should I use .get() with dictionaries in string problems?

Using my_dict.get(key, default_value) prevents your code from throwing a KeyError if the character hasn’t been added to the dictionary yet. It sets up a safe starting fallback value instead.

6. Is it better to use built-in functions or write custom logic?

When learning, write out the custom logic manually to build your problem-solving skills. When writing production code, stick to built-in functions since they are highly optimized and run much faster.

7. How do I check if a string contains only letters?

You can use the built-in string method my_string.isalpha(), which returns True if the string contains only letters and has at least one character.

8. What is the time complexity of searching a value in a list?

Searching a standard list using loops or the in operator takes linear time, or $O(n)$, because Python checks each element one by one from the start.

9. Can a string be converted into a list of characters?

Yes, passing a string into the list constructor—list("hello")—creates a list of individual characters: ['h', 'e', 'l', 'l', 'o'].

10. What is a two-pointer approach?

It is a technique where two integer variables (pointers) index a collection from different positions (often the start and the end). They move toward each other to process data efficiently, saving memory and processing time.


Final Thoughts

If you are a self-taught programmer or a recent graduate preparing for technical interviews, don’t rush through these problems. Type out the code solutions manually rather than copying and pasting them. Try changing values to see where the logic breaks.

These 15 foundational challenges are great for building programmatic logic. However, if you already understand runtime complexities and feel comfortable with advanced multi-pointer problems, you should skip these introductory exercises and dive straight into intermediate LeetCode or HackerRank tracks instead.

What problem structure did you find trickier to wrap your head around—arrays or strings? Let me know in the comments below!

check other blog :- click here

Leave a Comment