Python Data Strutures and Algorithms (6 Part Series)
1 Part 1: Introduction to Data Structures and Algorithms (DSA) in Python
2 Part 2: Arrays, Lists, and Strings – Patterns, Tricks, and Pitfalls in Python
… 2 more parts…
3 Part 3: Stacks and Queues – Core Concepts and Python Implementations
4 🧮 Part 4: Hash Maps and Sets in Python – Lookups, Frequencies, and Fast Problem Solving
5 Part 5: Recursion and Backtracking – Solving Complex Problems Elegantly in Python
6 Part 6: Sorting Algorithms in Python – Concepts, Code, and Complexity
Introduction
Arrays (or lists in Python) and strings are among the most common data structures you’ll use. They form the backbone of many algorithms and interview questions.
In this post, we’ll explore:
Python’s built-in list and string capabilities
Essential algorithmic patterns: sliding window, two pointers, prefix sum
Real-world problems and how to solve them
Best practices and Pythonic shortcuts
1️⃣ Python Lists: More Than Just Arrays
Python lists are dynamic arrays that can grow or shrink in size.
<span>arr</span> <span>=</span> <span>[</span><span>1</span><span>,</span> <span>2</span><span>,</span> <span>3</span><span>]</span><span>arr</span><span>.</span><span>append</span><span>(</span><span>4</span><span>)</span> <span># [1, 2, 3, 4] </span><span>arr</span><span>.</span><span>pop</span><span>()</span> <span># [1, 2, 3] </span><span>arr</span><span>.</span><span>insert</span><span>(</span><span>1</span><span>,</span> <span>10</span><span>)</span> <span># [1, 10, 2, 3] </span><span>del</span> <span>arr</span><span>[</span><span>0</span><span>]</span> <span># [10, 2, 3] </span><span>arr</span> <span>=</span> <span>[</span><span>1</span><span>,</span> <span>2</span><span>,</span> <span>3</span><span>]</span> <span>arr</span><span>.</span><span>append</span><span>(</span><span>4</span><span>)</span> <span># [1, 2, 3, 4] </span><span>arr</span><span>.</span><span>pop</span><span>()</span> <span># [1, 2, 3] </span><span>arr</span><span>.</span><span>insert</span><span>(</span><span>1</span><span>,</span> <span>10</span><span>)</span> <span># [1, 10, 2, 3] </span><span>del</span> <span>arr</span><span>[</span><span>0</span><span>]</span> <span># [10, 2, 3] </span>arr = [1, 2, 3] arr.append(4) # [1, 2, 3, 4] arr.pop() # [1, 2, 3] arr.insert(1, 10) # [1, 10, 2, 3] del arr[0] # [10, 2, 3]
Enter fullscreen mode Exit fullscreen mode
List Slicing
<span>nums</span> <span>=</span> <span>[</span><span>1</span><span>,</span> <span>2</span><span>,</span> <span>3</span><span>,</span> <span>4</span><span>,</span> <span>5</span><span>]</span><span>print</span><span>(</span><span>nums</span><span>[</span><span>1</span><span>:</span><span>4</span><span>])</span> <span># [2, 3, 4] </span><span>print</span><span>(</span><span>nums</span><span>[::</span><span>-</span><span>1</span><span>])</span> <span># [5, 4, 3, 2, 1] – reversed </span><span>nums</span> <span>=</span> <span>[</span><span>1</span><span>,</span> <span>2</span><span>,</span> <span>3</span><span>,</span> <span>4</span><span>,</span> <span>5</span><span>]</span> <span>print</span><span>(</span><span>nums</span><span>[</span><span>1</span><span>:</span><span>4</span><span>])</span> <span># [2, 3, 4] </span><span>print</span><span>(</span><span>nums</span><span>[::</span><span>-</span><span>1</span><span>])</span> <span># [5, 4, 3, 2, 1] – reversed </span>nums = [1, 2, 3, 4, 5] print(nums[1:4]) # [2, 3, 4] print(nums[::-1]) # [5, 4, 3, 2, 1] – reversed
Enter fullscreen mode Exit fullscreen mode
Slicing is your best friend in array problems.
2️⃣ Strings in Python
Python strings are immutable and extremely versatile.
<span>s</span> <span>=</span> <span>"</span><span>hello</span><span>"</span><span>print</span><span>(</span><span>s</span><span>.</span><span>upper</span><span>())</span> <span># "HELLO" </span><span>print</span><span>(</span><span>s</span><span>[</span><span>1</span><span>:</span><span>4</span><span>])</span> <span># "ell" </span><span>print</span><span>(</span><span>"</span><span>h</span><span>"</span> <span>in</span> <span>s</span><span>)</span> <span># True </span><span>s</span> <span>=</span> <span>"</span><span>hello</span><span>"</span> <span>print</span><span>(</span><span>s</span><span>.</span><span>upper</span><span>())</span> <span># "HELLO" </span><span>print</span><span>(</span><span>s</span><span>[</span><span>1</span><span>:</span><span>4</span><span>])</span> <span># "ell" </span><span>print</span><span>(</span><span>"</span><span>h</span><span>"</span> <span>in</span> <span>s</span><span>)</span> <span># True </span>s = "hello" print(s.upper()) # "HELLO" print(s[1:4]) # "ell" print("h" in s) # True
Enter fullscreen mode Exit fullscreen mode
String Tricks
<span># Reversing a string </span><span>reversed_s</span> <span>=</span> <span>s</span><span>[::</span><span>-</span><span>1</span><span>]</span><span># Check for palindrome </span><span>def</span> <span>is_palindrome</span><span>(</span><span>s</span><span>):</span><span>return</span> <span>s</span> <span>==</span> <span>s</span><span>[::</span><span>-</span><span>1</span><span>]</span><span># Reversing a string </span><span>reversed_s</span> <span>=</span> <span>s</span><span>[::</span><span>-</span><span>1</span><span>]</span> <span># Check for palindrome </span><span>def</span> <span>is_palindrome</span><span>(</span><span>s</span><span>):</span> <span>return</span> <span>s</span> <span>==</span> <span>s</span><span>[::</span><span>-</span><span>1</span><span>]</span># Reversing a string reversed_s = s[::-1] # Check for palindrome def is_palindrome(s): return s == s[::-1]
Enter fullscreen mode Exit fullscreen mode
3️⃣ Pattern: Two Pointers
Use two pointers to scan a list or string from both ends or at different speeds.
Example: Is a list a palindrome?
<span>def</span> <span>is_palindrome</span><span>(</span><span>lst</span><span>):</span><span>left</span><span>,</span> <span>right</span> <span>=</span> <span>0</span><span>,</span> <span>len</span><span>(</span><span>lst</span><span>)</span> <span>-</span> <span>1</span><span>while</span> <span>left</span> <span><</span> <span>right</span><span>:</span><span>if</span> <span>lst</span><span>[</span><span>left</span><span>]</span> <span>!=</span> <span>lst</span><span>[</span><span>right</span><span>]:</span><span>return</span> <span>False</span><span>left</span> <span>+=</span> <span>1</span><span>right</span> <span>-=</span> <span>1</span><span>return</span> <span>True</span><span>def</span> <span>is_palindrome</span><span>(</span><span>lst</span><span>):</span> <span>left</span><span>,</span> <span>right</span> <span>=</span> <span>0</span><span>,</span> <span>len</span><span>(</span><span>lst</span><span>)</span> <span>-</span> <span>1</span> <span>while</span> <span>left</span> <span><</span> <span>right</span><span>:</span> <span>if</span> <span>lst</span><span>[</span><span>left</span><span>]</span> <span>!=</span> <span>lst</span><span>[</span><span>right</span><span>]:</span> <span>return</span> <span>False</span> <span>left</span> <span>+=</span> <span>1</span> <span>right</span> <span>-=</span> <span>1</span> <span>return</span> <span>True</span>def is_palindrome(lst): left, right = 0, len(lst) - 1 while left < right: if lst[left] != lst[right]: return False left += 1 right -= 1 return True
Enter fullscreen mode Exit fullscreen mode
Example: Remove Duplicates from Sorted Array
<span>def</span> <span>remove_duplicates</span><span>(</span><span>nums</span><span>):</span><span>if</span> <span>not</span> <span>nums</span><span>:</span><span>return</span> <span>0</span><span>i</span> <span>=</span> <span>0</span><span>for</span> <span>j</span> <span>in</span> <span>range</span><span>(</span><span>1</span><span>,</span> <span>len</span><span>(</span><span>nums</span><span>)):</span><span>if</span> <span>nums</span><span>[</span><span>j</span><span>]</span> <span>!=</span> <span>nums</span><span>[</span><span>i</span><span>]:</span><span>i</span> <span>+=</span> <span>1</span><span>nums</span><span>[</span><span>i</span><span>]</span> <span>=</span> <span>nums</span><span>[</span><span>j</span><span>]</span><span>return</span> <span>i</span> <span>+</span> <span>1</span><span>def</span> <span>remove_duplicates</span><span>(</span><span>nums</span><span>):</span> <span>if</span> <span>not</span> <span>nums</span><span>:</span> <span>return</span> <span>0</span> <span>i</span> <span>=</span> <span>0</span> <span>for</span> <span>j</span> <span>in</span> <span>range</span><span>(</span><span>1</span><span>,</span> <span>len</span><span>(</span><span>nums</span><span>)):</span> <span>if</span> <span>nums</span><span>[</span><span>j</span><span>]</span> <span>!=</span> <span>nums</span><span>[</span><span>i</span><span>]:</span> <span>i</span> <span>+=</span> <span>1</span> <span>nums</span><span>[</span><span>i</span><span>]</span> <span>=</span> <span>nums</span><span>[</span><span>j</span><span>]</span> <span>return</span> <span>i</span> <span>+</span> <span>1</span>def remove_duplicates(nums): if not nums: return 0 i = 0 for j in range(1, len(nums)): if nums[j] != nums[i]: i += 1 nums[i] = nums[j] return i + 1
Enter fullscreen mode Exit fullscreen mode
Use when you need to compare or update positions in-place.
4️⃣ Pattern: Sliding Window
Efficiently track values over a moving range.
Example: Max sum of subarray of size k
<span>def</span> <span>max_subarray_sum</span><span>(</span><span>nums</span><span>,</span> <span>k</span><span>):</span><span>window_sum</span> <span>=</span> <span>sum</span><span>(</span><span>nums</span><span>[:</span><span>k</span><span>])</span><span>max_sum</span> <span>=</span> <span>window_sum</span><span>for</span> <span>i</span> <span>in</span> <span>range</span><span>(</span><span>k</span><span>,</span> <span>len</span><span>(</span><span>nums</span><span>)):</span><span>window_sum</span> <span>+=</span> <span>nums</span><span>[</span><span>i</span><span>]</span> <span>-</span> <span>nums</span><span>[</span><span>i</span> <span>-</span> <span>k</span><span>]</span><span>max_sum</span> <span>=</span> <span>max</span><span>(</span><span>max_sum</span><span>,</span> <span>window_sum</span><span>)</span><span>return</span> <span>max_sum</span><span>def</span> <span>max_subarray_sum</span><span>(</span><span>nums</span><span>,</span> <span>k</span><span>):</span> <span>window_sum</span> <span>=</span> <span>sum</span><span>(</span><span>nums</span><span>[:</span><span>k</span><span>])</span> <span>max_sum</span> <span>=</span> <span>window_sum</span> <span>for</span> <span>i</span> <span>in</span> <span>range</span><span>(</span><span>k</span><span>,</span> <span>len</span><span>(</span><span>nums</span><span>)):</span> <span>window_sum</span> <span>+=</span> <span>nums</span><span>[</span><span>i</span><span>]</span> <span>-</span> <span>nums</span><span>[</span><span>i</span> <span>-</span> <span>k</span><span>]</span> <span>max_sum</span> <span>=</span> <span>max</span><span>(</span><span>max_sum</span><span>,</span> <span>window_sum</span><span>)</span> <span>return</span> <span>max_sum</span>def max_subarray_sum(nums, k): window_sum = sum(nums[:k]) max_sum = window_sum for i in range(k, len(nums)): window_sum += nums[i] - nums[i - k] max_sum = max(max_sum, window_sum) return max_sum
Enter fullscreen mode Exit fullscreen mode
Use when dealing with contiguous sequences like subarrays, substrings, etc.
5️⃣ Pattern: Prefix Sum
Prefix sum helps in range sum queries and cumulative processing.
Example: Range sum query
<span>def</span> <span>prefix_sum</span><span>(</span><span>nums</span><span>):</span><span>prefix</span> <span>=</span> <span>[</span><span>0</span><span>]</span><span>for</span> <span>num</span> <span>in</span> <span>nums</span><span>:</span><span>prefix</span><span>.</span><span>append</span><span>(</span><span>prefix</span><span>[</span><span>-</span><span>1</span><span>]</span> <span>+</span> <span>num</span><span>)</span><span>return</span> <span>prefix</span><span># Sum of elements from index i to j: prefix[j+1] - prefix[i] </span><span>def</span> <span>prefix_sum</span><span>(</span><span>nums</span><span>):</span> <span>prefix</span> <span>=</span> <span>[</span><span>0</span><span>]</span> <span>for</span> <span>num</span> <span>in</span> <span>nums</span><span>:</span> <span>prefix</span><span>.</span><span>append</span><span>(</span><span>prefix</span><span>[</span><span>-</span><span>1</span><span>]</span> <span>+</span> <span>num</span><span>)</span> <span>return</span> <span>prefix</span> <span># Sum of elements from index i to j: prefix[j+1] - prefix[i] </span>def prefix_sum(nums): prefix = [0] for num in nums: prefix.append(prefix[-1] + num) return prefix # Sum of elements from index i to j: prefix[j+1] - prefix[i]
Enter fullscreen mode Exit fullscreen mode
Reduces repeated computation in range-based problems.
🧪 6️⃣ Practice Problems
Problem | Pattern | Tip |
---|---|---|
Two Sum | Hashing / Two Pointers | Use a set for complements |
Maximum Subarray | Kadane’s Algorithm | Track max ending at current index |
Longest Substring Without Repeating Characters | Sliding Window | Use a set or dict for seen chars |
Palindrome Check | Two Pointers | Compare left and right |
Product of Array Except Self | Prefix & Suffix Arrays | Avoid division |
Best Practices
️ Know when to use in-place operations to save space
️ Use enumerate() to loop with index
️ Avoid += on strings in loops (use ”.join() instead)
️ Leverage collections.Counter, set, and defaultdict for advanced use cases
Avoid nested loops unless necessary — try sliding window or hashing
🧠 Summary
️ Lists and strings are the foundation of most coding problems
️ Learn and practice patterns like two pointers, sliding window, and prefix sums
️ Python’s expressive syntax helps solve these problems cleanly and concisely
️ Build your DSA muscle memory with hands-on problems using these patterns
Coming Up Next:
Part 3: Stacks and Queues – Theory, Python Implementations, and Interview Classics
We’ll explore:
- Real-world uses of stacks & queues
- How to implement with Python lists and deque
- Problems like parentheses validation, undo/redo, and level-order traversal
Got a favorite array/string trick? Or stuck on a pattern? Drop a comment and let’s chat! 🧩
Python Data Strutures and Algorithms (6 Part Series)
1 Part 1: Introduction to Data Structures and Algorithms (DSA) in Python
2 Part 2: Arrays, Lists, and Strings – Patterns, Tricks, and Pitfalls in Python
… 2 more parts…
3 Part 3: Stacks and Queues – Core Concepts and Python Implementations
4 🧮 Part 4: Hash Maps and Sets in Python – Lookups, Frequencies, and Fast Problem Solving
5 Part 5: Recursion and Backtracking – Solving Complex Problems Elegantly in Python
6 Part 6: Sorting Algorithms in Python – Concepts, Code, and Complexity
原文链接:Part 2: Arrays, Lists, and Strings – Patterns, Tricks, and Pitfalls in Python
暂无评论内容