Skip to content

Commit 10119a3

Browse files
Merge branch 'main' into main
2 parents a1e9742 + 78f7469 commit 10119a3

File tree

9 files changed

+1234
-1
lines changed

9 files changed

+1234
-1
lines changed
Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
---
2+
title: 'Mastering Data Structures in Python'
3+
sidebar_label: Data Structures
4+
authors: [santhosh-siddhardha]
5+
tags: [data-structures, python, best-practices]
6+
date: 2024-07-07
7+
hide_table_of_contents: true
8+
---
9+
10+
Data structures are essential components in computer science, enabling efficient data storage, manipulation, and retrieval. In Python, a variety of built-in data structures are available, each suited for specific tasks. This article aims to provide a comprehensive guide to mastering these data structures, including their usage, advantages, and best practices.
11+
12+
## Overview of Data Structures
13+
14+
### Types of Data Structures
15+
16+
1. **Primitive Data Structures**
17+
- Integers
18+
- Floats
19+
- Strings
20+
- Booleans
21+
22+
2. **Non-Primitive Data Structures**
23+
- Lists
24+
- Tuples
25+
- Dictionaries
26+
- Sets
27+
28+
## Lists
29+
30+
### Introduction
31+
32+
- Lists are ordered, mutable collections of items.
33+
- They allow duplicate elements.
34+
- Lists can hold heterogeneous data types.
35+
36+
### Basic Operations
37+
38+
```python
39+
# Creating a list
40+
my_list = [1, 2, 3, 'apple', 'banana']
41+
42+
# Accessing elements
43+
print(my_list[0]) # Output: 1
44+
print(my_list[-1]) # Output: 'banana'
45+
46+
# Modifying elements
47+
my_list[0] = 10
48+
49+
# Adding elements
50+
my_list.append('cherry')
51+
my_list.insert(2, 'orange')
52+
53+
# Removing elements
54+
my_list.remove('apple')
55+
del my_list[1]
56+
popped_item = my_list.pop()
57+
58+
# Slicing
59+
sub_list = my_list[1:3]
60+
61+
print(my_list) # Output: [10, 'orange', 3, 'banana']
62+
print(popped_item) # Output: 'cherry'
63+
print(sub_list) # Output: ['orange', 3]
64+
```
65+
66+
### List Comprehensions
67+
68+
- A concise way to create lists.
69+
70+
```python
71+
squares = [x**2 for x in range(10)]
72+
print(squares) # Output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
73+
```
74+
75+
## Tuples
76+
77+
### Introduction
78+
79+
- Tuples are ordered, immutable collections of items.
80+
- They allow duplicate elements.
81+
- Tuples can hold heterogeneous data types.
82+
83+
### Basic Operations
84+
85+
```python
86+
# Creating a tuple
87+
my_tuple = (1, 2, 3, 'apple', 'banana')
88+
89+
# Accessing elements
90+
print(my_tuple[0]) # Output: 1
91+
print(my_tuple[-1]) # Output: 'banana'
92+
93+
# Slicing
94+
sub_tuple = my_tuple[1:3]
95+
print(sub_tuple) # Output: (2, 3)
96+
```
97+
98+
### Unpacking Tuples
99+
100+
```python
101+
a, b, c, d, e = my_tuple
102+
print(a, b, c, d, e) # Output: 1 2 3 apple banana
103+
```
104+
105+
## Dictionaries
106+
107+
### Introduction
108+
109+
- Dictionaries are unordered collections of key-value pairs.
110+
- Keys must be unique and immutable.
111+
- Values can be of any data type.
112+
113+
### Basic Operations
114+
115+
```python
116+
# Creating a dictionary
117+
my_dict = {'name': 'John', 'age': 25, 'city': 'New York'}
118+
119+
# Accessing elements
120+
print(my_dict['name']) # Output: John
121+
122+
# Modifying elements
123+
my_dict['age'] = 26
124+
125+
# Adding elements
126+
my_dict['job'] = 'Engineer'
127+
128+
# Removing elements
129+
del my_dict['city']
130+
popped_value = my_dict.pop('job')
131+
132+
# Dictionary methods
133+
keys = my_dict.keys()
134+
values = my_dict.values()
135+
items = my_dict.items()
136+
137+
print(my_dict) # Output: {'name': 'John', 'age': 26}
138+
print(popped_value) # Output: Engineer
139+
print(list(keys)) # Output: ['name', 'age']
140+
print(list(values)) # Output: ['John', 26]
141+
print(list(items)) # Output: [('name', 'John'), ('age', 26)]
142+
```
143+
144+
### Dictionary Comprehensions
145+
146+
```python
147+
squared_numbers = {x: x**2 for x in range(10)}
148+
print(squared_numbers) # Output: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
149+
```
150+
151+
## Sets
152+
153+
### Introduction
154+
155+
- Sets are unordered collections of unique elements.
156+
- They do not allow duplicate elements.
157+
158+
### Basic Operations
159+
160+
```python
161+
# Creating a set
162+
my_set = {1, 2, 3, 'apple'}
163+
164+
# Adding elements
165+
my_set.add('banana')
166+
167+
# Removing elements
168+
my_set.remove('apple')
169+
popped_item = my_set.pop()
170+
171+
# Set operations
172+
set1 = {1, 2, 3}
173+
set2 = {3, 4, 5}
174+
175+
union = set1 | set2
176+
intersection = set1 & set2
177+
difference = set1 - set2
178+
symmetric_difference = set1 ^ set2
179+
180+
print(my_set) # Output: {2, 3, 'banana'}
181+
print(popped_item) # Output: 1 (the popped element, which can be any element as sets are unordered)
182+
print(union) # Output: {1, 2, 3, 4, 5}
183+
print(intersection) # Output: {3}
184+
print(difference) # Output: {1, 2}
185+
print(symmetric_difference) # Output: {1, 2, 4, 5}
186+
```
187+
188+
## Advanced Data Structures
189+
190+
### Stacks
191+
192+
- Last In, First Out (LIFO) principle.
193+
- Can be implemented using lists.
194+
195+
```python
196+
stack = []
197+
198+
# Pushing elements
199+
stack.append(1)
200+
stack.append(2)
201+
202+
# Popping elements
203+
popped_element = stack.pop()
204+
205+
print(stack) # Output: [1]
206+
print(popped_element) # Output: 2
207+
```
208+
209+
### Queues
210+
211+
- First In, First Out (FIFO) principle.
212+
- Can be implemented using `collections.deque`.
213+
214+
```python
215+
from collections import deque
216+
217+
queue = deque()
218+
219+
# Enqueuing elements
220+
queue.append(1)
221+
queue.append(2)
222+
223+
# Dequeuing elements
224+
dequeued_element = queue.popleft()
225+
226+
print(queue) # Output: deque([2])
227+
print(dequeued_element) # Output: 1
228+
```
229+
230+
### Linked Lists
231+
232+
- Nodes containing data and pointers to the next node.
233+
- Can be implemented using classes.
234+
235+
```python
236+
class Node:
237+
def __init__(self, data):
238+
self.data = data
239+
self.next = None
240+
241+
class LinkedList:
242+
def __init__(self):
243+
self.head = None
244+
245+
def append(self, data):
246+
new_node = Node(data)
247+
if not self.head:
248+
self.head = new_node
249+
return
250+
last = self.head
251+
while last.next:
252+
last = last.next
253+
last.next = new_node
254+
255+
def print_list(self):
256+
current = self.head
257+
while current:
258+
print(current.data, end=" ")
259+
current = current.next
260+
print()
261+
262+
# Using the LinkedList class
263+
ll = LinkedList()
264+
ll.append(1)
265+
ll.append(2)
266+
ll.print_list() # Output: 1 2
267+
```
268+
269+
### Trees
270+
271+
- Hierarchical data structures with a root node and children nodes.
272+
- Can be implemented using classes.
273+
274+
```python
275+
class TreeNode:
276+
def __init__(self, data):
277+
self.data = data
278+
self.children = []
279+
280+
def add_child(self, child):
281+
self.children.append(child)
282+
283+
def print_tree(self):
284+
print(self.data)
285+
for child in self.children:
286+
child.print_tree()
287+
288+
# Using the TreeNode class
289+
root = TreeNode('root')
290+
child1 = TreeNode('child1')
291+
child2 = TreeNode('child2')
292+
root.add_child(child1)
293+
root.add_child(child2)
294+
root.print_tree()
295+
# Output:
296+
# root
297+
# child1
298+
# child2
299+
```
300+
301+
### Graphs
302+
303+
- Consist of vertices (nodes) and edges (connections between nodes).
304+
- Can be represented using adjacency lists or matrices.
305+
306+
```python
307+
class Graph:
308+
def __init__(self):
309+
self.graph = {}
310+
311+
def add_edge(self, u, v):
312+
if u not in self.graph:
313+
self.graph[u] = []
314+
self.graph[u].append(v)
315+
316+
def print_graph(self):
317+
for node in self.graph:
318+
print(node, '->', self.graph[node])
319+
320+
# Using the Graph class
321+
g = Graph()
322+
g.add_edge('A', 'B')
323+
g.add_edge('A', 'C')
324+
g.print_graph()
325+
# Output:
326+
# A -> ['B', 'C']
327+
```
328+
329+
## Conclusion
330+
331+
Understanding and mastering data structures in Python is crucial for efficient programming and problem-solving. By leveraging Python's built-in data structures and understanding how to implement more advanced structures, you can write more effective and optimized code. Remember to choose the right data structure for the task at hand to ensure your programs run efficiently and maintainably.

blog/authors.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,10 @@ pujan-sarkar:
5252
title: Cyber Security Enthusiast
5353
url: "https://github.com/Pujan-sarkar"
5454
image_url: https://avatars.githubusercontent.com/u/144250917?v=4
55+
56+
57+
santhosh-siddhardha:
58+
name: Lingamuneni Santhosh Siddhardha
59+
title: Software Engineer
60+
url: "https://github.com/Santhosh-Siddhardha"
61+
image_url: https://avatars.githubusercontent.com/u/103999924?v=4

dsa-problems/leetcode-problems/0100-0199.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ export const problems = [
338338
"problemName": "154. Find Minimum in Rotated Sorted Ar...",
339339
"difficulty": "Hard",
340340
"leetCodeLink": "https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/",
341-
"solutionLink": "#"
341+
"solutionLink": "/dsa-solutions/lc-solutions/0100-0199/find-minimum-in-rotated-sorted-array-II"
342342
},
343343
{
344344
"problemName": "155. Min Stack",

0 commit comments

Comments
 (0)