【Python常见数据结构操作-持续更新】
在Python中,常用的集合类型有列表(list)、元组(tuple)、集合(set)和字典(dict),双端队列(deque)、堆(heapq)、计数器(Counter)和有序字典(OrderedDict)。以下是它们的创建、添加和删除操作的详细说明和示例:
常见数据结构操作
1. 列表(list)
创建:
my_list = [] # 创建空列表
my_list = [1, 2, 3, 4, 5] # 创建包含元素的列表
添加:
my_list.append(6) # 在列表末尾添加元素
my_list.extend([7, 8, 9]) # 在列表末尾添加另一个列表的元素
my_list.insert(0, 0) # 在指定位置插入元素,这里在列表开头插入0
删除:
my_list.remove(0) # 移除列表中第一个出现的指定值
del my_list[0] # 根据索引删除元素
my_list.pop() # 移除列表末尾的元素
my_list.pop(0) # 根据索引移除元素
my_list.clear() # 清空列表
2. 元组(tuple)
创建:
my_tuple = () # 创建空元组
my_tuple = (1, 2, 3, 4, 5) # 创建包含元素的元组
元组是不可变的,因此无法添加或删除元素。但是可以通过连接元组来创建新的元组:
my_tuple = my_tuple + (6, 7, 8) # 将两个元组连接为一个新元组
3. 集合(set)
创建:
my_set = set() # 创建空集合
my_set = {1, 2, 3, 4, 5} # 创建包含元素的集合
添加:
my_set.add(6) # 向集合添加元素
my_set.update([7, 8, 9]) # 向集合添加另一个集合、列表或元组的元素
删除:
my_set.remove(1) # 移除集合中的指定元素,如果元素不存在会引发KeyError
my_set.discard(1) # 移除集合中的指定元素,如果元素不存在不会引发错误
my_set.pop() # 移除并返回集合中的任意一个元素,如果集合为空会引发KeyError
my_set.clear() # 清空集合
4. 字典(dict)
创建:
my_dict = {} # 创建空字典
my_dict = {'a': 1, 'b': 2, 'c': 3} # 创建包含键值对的字典
添加:
my_dict['d'] = 4 # 向字典添加键值对
my_dict.update({'e': 5, 'f': 6}) # 使用另一个字典更新当前字典,添加或覆盖键值对
删除:
del my_dict['a'] # 根据键删除键值对
my_dict.pop('b') # 根据键移除并返回键值对的值,如果键不存在会引发KeyError
my_dict.popitem() # 移除并返回字典中的最后一个键值对(Python 3.7+)
my_dict.clear() # 清空字典
5. 双端队列(deque)
创建:
from collections import deque
my_deque = deque() # 创建空双端队列
my_deque = deque([1, 2, 3, 4, 5]) # 创建包含元素的双端队列
添加:
my_deque.append(6) # 在双端队列右侧添加元素
my_deque.appendleft(0) # 在双端队列左侧添加元素
my_deque.extend([7, 8, 9]) # 在双端队列右侧扩展另一个可迭代对象的元素
my_deque.extendleft([-1, -2, -3]) # 在双端队列左侧扩展另一个可迭代对象的元素,注意元素的顺序会被反转
删除:
my_deque.pop() # 移除并返回双端队列右侧的元素
my_deque.popleft() # 移除并返回双端队列左侧的元素
my_deque.remove(1) # 移除双端队列中第一个出现的指定值
my_deque.clear() # 清空双端队列
6. 堆(heapq)
创建:
import heapq
my_heap = [] # 创建空堆,实际上就是一个列表
my_heap = [1, 2, 3, 4, 5] # 创建包含元素的堆
heapq.heapify(my_heap) # 将列表转换为堆
添加:
heapq.heappush(my_heap, 6) # 向堆中添加元素
删除:
heapq.heappop(my_heap) # 移除并返回堆中最小的元素
7. 计数器(Counter)
创建:
from collections import Counter
my_counter = Counter() # 创建空计数器
my_counter = Counter('abracadabra') # 创建包含元素计数的计数器
添加:
my_counter.update('abcde') # 使用另一个可迭代对象更新计数器,添加或覆盖元素计数
删除:
del my_counter['a'] # 删除计数器中的指定元素
my_counter.subtract('abcde') # 使用另一个可迭代对象减少计数器中元素的计数
8. 有序字典(OrderedDict)
创建:
from collections import OrderedDict
my_ordered_dict = OrderedDict() # 创建空有序字典
my_ordered_dict = OrderedDict([('a', 1), ('b', 2), ('c', 3)]) # 创建包含键值对的有序字典
添加:
my_ordered_dict['d'] = 4 # 向有序字典添加键值对
my_ordered_dict.update({'e': 5, 'f': 6}) # 使用另一个字典更新有序字典,添加或覆盖键值对
删除:
del my_ordered_dict['a'] # 根据键删除键值对
my_ordered_dict.pop('b') # 根据键移除并返回键值对的值,如果键不存在会引发KeyError
my_ordered_dict.popitem() # 移除并返回有序字典中的最后一个键值对
my_ordered_dict.clear() # 清空有序字典
链表
在Python中没有内置的链表数据结构,但是可以使用列表(list)和双端队列(deque)来实现类似链表的操作。以下是列表和双端队列的一些常见操作的详细说明和示例:
1. 列表(list)
创建:
my_list = [] # 创建空列表
my_list = [1, 2, 3, 4, 5] # 创建包含元素的列表
添加:
my_list.append(6) # 在列表末尾添加元素
my_list.insert(0, 0) # 在指定位置插入元素,这里在列表开头插入0
删除:
my_list.remove(0) # 移除列表中第一个出现的指定值
del my_list[0] # 根据索引删除元素
my_list.pop() # 移除列表末尾的元素
my_list.pop(0) # 根据索引移除元素
my_list.clear() # 清空列表
2. 双端队列(deque)
创建:
from collections import deque
my_deque = deque() # 创建空双端队列
my_deque = deque([1, 2, 3, 4, 5]) # 创建包含元素的双端队列
添加:
my_deque.append(6) # 在双端队列右侧添加元素
my_deque.appendleft(0) # 在双端队列左侧添加元素
删除:
my_deque.pop() # 移除并返回双端队列右侧的元素
my_deque.popleft() # 移除并返回双端队列左侧的元素
my_deque.remove(1) # 移除双端队列中第一个出现的指定值
my_deque.clear() # 清空双端队列
需要注意的是,列表和双端队列在实现链表操作时的性能差异。列表在头部插入和删除元素时的时间复杂度为O(n),而双端队列在头部和尾部插入和删除元素时的时间复杂度为O(1)。因此,如果需要频繁地在头部插入和删除元素,建议使用双端队列。
自定义链表操作
在Python中,链表可以使用自定义类来实现。以下是链表的一些常见操作的详细说明和示例:
首先,定义链表节点类和链表类:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class LinkedList:
def __init__(self):
self.head = None
- 创建链表:
my_linked_list = LinkedList() # 创建空链表
- 向链表添加元素:
def add(self, val):
if not self.head:
self.head = ListNode(val)
else:
current = self.head
while current.next:
current = current.next
current.next = ListNode(val)
LinkedList.add = add
my_linked_list.add(1) # 向链表添加元素1
my_linked_list.add(2) # 向链表添加元素2
- 在链表指定位置插入元素:
def insert(self, index, val):
if index == 0:
self.head = ListNode(val, self.head)
else:
current = self.head
for _ in range(index - 1):
if not current:
raise IndexError("Index out of range")
current = current.next
if not current:
raise IndexError("Index out of range")
current.next = ListNode(val, current.next)
LinkedList.insert = insert
my_linked_list.insert(1, 3) # 在链表索引为1的位置插入元素3
- 删除链表中的元素:
def remove(self, val):
if not self.head:
raise ValueError("Empty list")
if self.head.val == val:
self.head = self.head.next
else:
current = self.head
while current.next and current.next.val != val:
current = current.next
if not current.next:
raise ValueError("Value not found")
current.next = current.next.next
LinkedList.remove = remove
my_linked_list.remove(3) # 删除链表中值为3的元素
- 获取链表中元素的索引:
def index(self, val):
current = self.head
index = 0
while current:
if current.val == val:
return index
current = current.next
index += 1
raise ValueError("Value not found")
LinkedList.index = index
index = my_linked_list.index(2) # 获取链表中值为2的元素的索引
- 获取链表的长度:
def length(self):
current = self.head
count = 0
while current:
count += 1
current = current.next
return count
LinkedList.length = length
length = my_linked_list.length() # 获取链表的长度
- 判断链表是否为空:
def is_empty(self):
return self.head is None
LinkedList.is_empty = is_empty
empty = my_linked_list.is_empty() # 判断链表是否为空
- 遍历链表并打印元素:
def traverse(self):
current = self.head
while current:
print(current.val, end=' -> ')
current = current.next
print('None')
LinkedList.traverse = traverse
my_linked_list.traverse() # 遍历链表并打印元素
字符串操作示例:
1. 创建字符串:
my_str = '' # 创建空字符串
my_str = 'Hello, World!' # 创建包含字符的字符串
2. 连接字符串:
my_str = 'Hello' + ', ' + 'World!' # 使用+连接字符串
my_str = ' '.join(['Hello', 'World!']) # 使用join连接字符串列表
3. 访问字符串中的元素:
first_char = my_str[0] # 访问字符串中的第一个字符
last_char = my_str[-1] # 访问字符串中的最后一个字符
4. 修改字符串:
字符串在Python中是不可变的,因此无法直接修改字符串中的元素。但是可以通过创建新的字符串来实现修改:
my_str = 'Hello, World!'
my_str = my_str.replace('World', 'Python') # 替换字符串中的一部分
5. 删除字符串中的元素:
同样,由于字符串是不可变的,因此无法直接删除字符串中的元素。但是可以通过创建新的字符串来实现删除:
my_str = 'Hello, World!'
my_str = my_str.replace(' ', '') # 删除字符串中的所有空格
6. 查找字符串中的元素:
index = my_str.index('World') # 查找子字符串在字符串中的位置,如果子字符串不存在会引发ValueError
index = my_str.find('World') # 查找子字符串在字符串中的位置,如果子字符串不存在会返回-1
7. 切分字符串:
words = my_str.split(' ') # 使用空格切分字符串为单词列表
8. 大小写转换:
my_str = my_str.upper() # 将字符串转换为大写
my_str = my_str.lower() # 将字符串转换为小写
9. 去除字符串中的空格:
my_str = my_str.strip() # 去除字符串首尾的空格
my_str = my_str.lstrip() # 去除字符串开头的空格
my_str = my_str.rstrip() # 去除字符串末尾的空格
10. 判断字符串是否以某个子字符串开头或结尾:
is_start = my_str.startswith('Hello') # 判断字符串是否以'Hello'开头
is_end = my_str.endswith('!') # 判断字符串是否以'!'结尾
11. 判断字符串是否只包含数字、字母或数字和字母:
is_digit = my_str.isdigit() # 判断字符串是否只包含数字
is_alpha = my_str.isalpha() # 判断字符串是否只包含字母
is_alnum = my_str.isalnum() # 判断字符串是否只包含数字和字母
12. 获取字符串的长度:
length = len(my_str) # 获取字符串的长度
13. 格式化字符串:
my_str = 'Hello, {}!'.format('Python') # 使用format方法格式化字符串
my_str = f'Hello, {"Python"}!' # 使用f-string格式化字符串