python--数据结构

1.list 列表

1.1 特点

有序:列表按照插入顺序排列。
可变:可以添加,删除或者修改列表中的元素。
异构:包含不同类型的数据。
可重复:
可迭代对象:可以使用迭代器协议来遍历列表中的元素,列表支持两种基本的迭代方法:for循环和迭代器协议。
ps:迭代器协议要求对象实现两个特殊方法:

iter():返回一个迭代器对象

next():返回迭代器中的下一个值,如果没有更多值时,它会抛出StopIteration异常。

1.2 列表的创建

t = []
t = [1,2,3]

1.3 其他类型转化成列表

tuple1 = (1, 2, 3)
set1 = {1, 2, 3}
dict1 = {1: 'a', 2: 'b', 3: 'c'}
str1 = "123"
list1 = list(tuple1)
list2 = list(set1)
list3 = list(dict1)
list4 = list(str1)
print(list1, type(list1))
print(list2, type(list2))
print(list3, type(list3))
print(list4, type(list4))
 
out:
[1, 2, 3] <class 'list'>
[1, 2, 3] <class 'list'>
[1, 2, 3] <class 'list'>
[1, 2, 3] <class 'list'>

1.4 列表推导式

1.5 列表的增加

列表是可变对象,可以在队尾增加元素,效率很高。

list1 = [1, 2, 3]
print(list1, id(list1))
list1.append(4)
print(list1, id(list1))
list1.extend([5,6]) #合并两个列表
list1.insert(0,0.5)
list1.insert(3,2.5)
print(list1, id(list1))
 
out:
[1, 2, 3] 2984233256832
[1, 2, 3, 4] 2984233256832
[0.5, 1, 2, 2.5, 3, 4, 5, 6] 2984233256832

1.6 列表的运算

使用*运算会新建一个列表
使用+运算不会新建一个列表

1.7 列表的删除

(1)remove() 根据元素值进行删除,在不确定索引之确定值的情况下使用这个方法。这个方法只删除第一个匹配的元素,若列表中不存在对应值,则抛错ValueError
(2)pop() 根据索引值删除元素,不指定的时候,默认删除队尾元素,pop函数有返回值,返回的内容是删除的索引下标。
(3)clear() 清空列表内容,保留列表本身,可以节省新建开销,不需要新建列表。

1.8 列表的修改

可以通过下标,切片方法修改范围来修改列表的内容。

1.9 列表的查询

列表的查询时in运算

2.0 列表的内置方法

(1)sort
a.sort()
(2)sorted :和sort基本类似,但是不改变原列表顺序,而是返回新列表,要定义
变量接受。
a = [1,3,1]
b = sorted(a)
(3)copy,建立列表的副本,内容一致,id不同。(注意:嵌套结构要用deepcopy)

2.tuple 元组

2.1 特点

有序:元组中的元素是有序的
不可变:一旦创建,元组内容不能被修改
异构:包含不同类型的数据。
可迭代对象
可重复

2.2 元组的创建

t = ()
t=(1,)  # 注意这个逗号必不可少
t= 1, #这样也会生成一个元组的
print(type(t))
t2=(1)  # 没有逗号是这个数据本身的类型,不是元组
print(type(t2))
 
out:
<class 'tuple'>
<class 'int'>

2.3 其他类型转化成元组

list1=[1,2,3]
set1={1,2,3}
dict1={1:'a',2:'b',3:'c'}
str1 = "123"
t1=tuple(list1)
t2=tuple(set1)
t3=tuple(dict1)
t4=tuple(str1)
print(t1,type(t1))
print(t2,type(t2))
print(t3,type(t3))
print(t4,type(t4))

out:
(1, 2, 3) <class 'tuple'>
(1, 2, 3) <class 'tuple'>
(1, 2, 3) <class 'tuple'>
(1, 2, 3) <class 'tuple'>

2.4 元组的增加和删除和修改

增加:
元组是不可变对象,不能增加,所以只能新建

t1 = (1, 2, 3)
print(t1, id(t1))
t1 += (4,)
print(t1, id(t1))
t1 = t1 * 2
print(t1, id(t1))
 
out:
(1, 2, 3) 2276949975616
(1, 2, 3, 4) 2276949965376
(1, 2, 3, 4, 1, 2, 3, 4) 2276949924432

删除:
元组是不可变对象,所以元素不能被删除,但是整个元组可以被删除,del 元组名即可。
修改:
不可变,不能修改,可以把元组转成列表修改之后,再改成元组,实际上还是新建一个元组。
元素是不可变对象不能修改,元素是可变对象,可以修改

t1 = (1, 2, 3, [4, 5])
#t1[1] = 888  # 修改元素时,若它是不可变对象会报错
t1[3][0] = 666  # 修改元素时,若它是可变对象可修改
print(t1)
 
out:
(1, 2, 3, [666, 5])

2.5 元组的查询

元组的查询时in运算

t = (0, 1, 2)
print(0 in t)
print(666 in t)
print(888 not in t)
out:
True
False
True

切片:

t = ('今日', '头条', '关于', '元组', '元组', 1, 1)
# 打印元组t的前2个元素
print(t[:2])
# 倒序打印元组t
print(t[::-1])
# 打印元组的第4、和第5个元素。
print(t[3:5])
 
out:
('今日', '头条')
(1, 1, '元组', '元组', '关于', '头条', '今日')
('元组', '元组')

3.dictionary 字典

3.1 特点

有序:从python3.7版本开始得到保证,当创建一个字典并按一定的顺序插入键值对的时候,这些键值对在字典的顺序中会被保持。
可变:可以添加,删除或者修改字典中的元素。
异构:包含不同类型的数据。
可重复:字典中的键是不可以重复的,值可以重复,并且键必须是不可变类型,比如字符串,数字,元组
可迭代对象:可以使用迭代器协议来遍历列表中的元素,列表支持两种基本的迭代方法:for循环和迭代器协议。

3.2 字典的创建

a = {}
b = dict()
c = {1:"a",2:"b",3:"c"}
#使用dict+zip创建字典
keys = [1,2,3]
values = ["a","b","c"]
a = dict(zip(keys,values))
print(a) # {1: 'a', 2: 'b', 3: 'c'}

zip()函数可以用来组合多个可迭代对象,并将对象中对应的元素打包成一个元组。然后返回这些元组组成的列表。
如果各个迭代器的元素不一致,则返回列表长度与最短的对象相同,利用*号操作符,可以将元组解压为列表。

a = [1,2,3]
b = [4,5,6]
c = [4,5,6,7,8]
#1. 打包为元组的列表
zipped = zip(a,b)
# <zip object at 0x000001C2715CA940> zip函数返回的是一个迭代器,这个迭代器在每次迭代时生成一个新的元组。
print((zipped))
# 因为没有被迭代,所以要获取实际的元组,需要遍历这个zip对象
# for i in zipped:
#     print(i)
# 或者使用可迭代对象返回
# print(dict(zipped)) # {1: 4, 2: 5, 3: 6}

#2.
temp1 = list(zip(a,c))         # 元素个数与最短的列表一致
print(temp1) #[(1, 4), (2, 5), (3, 6)]

#3.
temp2 = zip(*zipped)  # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
print(list(temp2)) #  [(1, 2, 3), (4, 5, 6)]

#4.
temp3,temp4 = zip(*zip(a,b))  # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
print(list(temp3))  # [1, 2, 3]
print(list(temp4))  # [4

3.3 其他类型转化为字典

(1)列表转字典

# 列表形式的键值对
list_of_tuples = [('name', 'Alice'), ('age', 25), ('job', 'Engineer')]
# 转换为字典
dictionary_from_list = dict(list_of_tuples)
print(dictionary_from_list) # {'name': 'Alice', 'age': 25, 'job': 'Engineer'}
```a
(2)元组转字典
```python
# 元组形式的键值对
tuple_of_tuples = (('name', 'Bob'), ('age', 30), ('job', 'Doctor'))
# 转换为字典
dictionary_from_tuple = dict(tuple_of_tuples)
print(dictionary_from_tuple) #{'name': 'Bob', 'age': 30, 'job': 'Doctor'}

(3) 字符串转字典

# 字符串形式的键值对
string_pairs = "name:Alice,age:25,job:Engineer"
# 分割字符串并转换为字典
pairs = string_pairs.split(',')
dictionary_from_string = {pair.split(':')[0]: pair.split(':')[1] for pair in pairs}
print(dictionary_from_string) #{'name': 'Alice', 'age': '25', 'job': 'Engineer'}

(4)从类实例的属性转字典

class Person:
    def __init__(self, name, age, job):
        self.name = name
        self.age = age
        self.job = job

# 创建类实例
person = Person('Charlie', 35, 'Teacher')
# 获取实例属性并转换为字典
dictionary_from_object = vars(person)
print(dictionary_from_object) # {'name': 'Charlie', 'age': 35, 'job': 'Teacher'}

(5)从多个列表/元组转字典
如果你有两个列表或元组,一个作为键,另一个作为值,可以使用zip()函数将它们组合起来,然后用dict()构造函数转换为字典。

# 键和值的列表
keys = ['name', 'age', 'job']
values = ['David', 40, 'Scientist']
# 使用 zip() 组合键和值,然后转换为字典
dictionary_from_keys_values = dict(zip(keys, values))
print(dictionary_from_keys_values) #{'name': 'David', 'age': 40, 'job': 'Scientist'}

字典的增加,修改,删除

向字典添加新内容的方法是增加新的键/值对,修改或删除已有键/值
(1)增加,修改

dict = {'Name':'zara','age':7,'class':'first'} 
dict['age'] = 8 #更新 
dict['a'] = 'a' #添加 dict

(2)删除
pop() : pop() 方法可以从字典中移除指定键的条目,并返回该键对应的值。如果键不存在,程序抛出 KeyError。

# 创建一个字典
my_dict = {'name': 'Alice', 'age': 25, 'job': 'Engineer'}
# 移除键 'age' 并获取其值
age = my_dict.pop('age') # my_dict.pop() 报错pop expected at least 1 argument, got 0
# 输出字典
print(my_dict)
# 输出移除的值
print(age) # 25

popitem():popitem() 方法随机移除并返回字典中的最后一对键值对。在 Python 3.7 及以上版本中,由于字典保持插入顺序,因此 popitem() 实际上会移除最新添加的键值对。

# 创建一个字典
my_dict = {'name': 'Alice', 'age': 25, 'job': 'Engineer'}
# 移除并返回最后一个键值对
last_item = my_dict.popitem()
# 输出字典
print(my_dict)
# 输出移除的键值对
print(last_item) # ('job', 'Engineer')

clear():方法清空整个字典,移除所有的键值对。

# 创建一个字典
my_dict = {'name': 'Alice', 'age': 25, 'job': 'Engineer'}
# 清空字典
my_dict.clear()
# 输出字典
print(my_dict)

字典的查询

(1) 直接使用键访问:
可以使用字典的键来直接访问对应的值。这种方法简单直观,但如果没有对应的键,程序会抛出 KeyError

# 创建一个字典
my_dict = {'name': 'Alice', 'age': 25, 'job': 'Engineer'}
# 查询 'name' 键对应的值
name = my_dict['name']
# 输出查询结果
print(name)

(2) get()方法
get() 方法用于安全地查询字典中的值。如果键不存在,get() 方法可以返回一个默认值,避免抛出异常。

# 创建一个字典
my_dict = {'name': 'Alice', 'age': 25, 'job': 'Engineer'}

# 查询 'name' 键对应的值,如果键不存在则返回 'Unknown'
name = my_dict.get('name', 'Unknown')

# 输出查询结果
print(name)

# 查询不存在的键 'address',默认返回 'Unknown'
address = my_dict.get('address', 'Unknown')

# 输出查询结果
print(address)

(3) setdefault()方法
setdefault() 方法类似于 get() 方法,但如果键不存在,则会在字典中添加该键并设置一个默认值。如果键存在,则返回该键对应的值。

# 创建一个字典
my_dict = {'name': 'Alice', 'age': 25, 'job': 'Engineer'}

# 查询 'name' 键对应的值,如果键不存在则添加默认值 'Unknown'
name = my_dict.setdefault('name', 'Unknown')

# 输出查询结果
print(name)

# 查询不存在的键 'address',并设置默认值 'Unknown'
address = my_dict.setdefault('address', 'Unknown')

# 输出查询结果
print(address)

# 输出完整的字典
print(my_dict)

(4)使用in操作符
可以使用 in 操作符检查字典中是否存在某个键,然后决定是否进行查询。

# 创建一个字典
my_dict = {'name': 'Alice', 'age': 25, 'job': 'Engineer'}

# 检查 'name' 是否在字典中
if 'name' in my_dict:
    name = my_dict['name']
else:
    name = 'Unknown'

# 输出查询结果
print(name)

# 检查 'address' 是否在字典中
if 'address' in my_dict:
    address = my_dict['address']
else:
    address = 'Unknown'

# 输出查询结果
print(address)

4.set 集合

4.1 特点

无序:集合中的元素没有固定的顺序,当你查看集合的内容时,元素的顺序可能会有所不同。这是因为集合内部是基于哈希表实现的,不保证元素的顺序。请注意,输出的顺序可能与原始添加的顺序不同,因为集合是无序的。
可变:集合是可变的,这意味着你可以使用方法如 add()、remove()、discard()、update() 等来添加或删除元素。但请注意,集合中的元素本身必须是不可变的类型,如字符串、数字或元组。
异构:集合可以包含不同类型的元素。例如,一个集合可以同时包含整数、字符串和浮点数。
不可重复:集合中的元素必须是唯一的,即不允许重复。如果你尝试添加重复的元素到集合中,集合会自动去除重复项,只保留一个副本。
可迭代:集合是可迭代的对象,可以使用 for 循环来遍历集合中的元素。

4.2 集合的创建

(1)
你可以使用花括号 {} 来创建一个集合。注意,空的花括号 {} 代表一个空字典,而不是一个空集合。因此,要创建一个空集合,你需要使用 set() 构造函数。

# 创建一个包含元素的集合
a  = {}
print(type(a)) # dict
my_set = {1, 2, 3, 'Alice', 4.5}
print(my_set) 
# 创建一个空集合
empty_set = set()
print(empty_set)

(2)使用 set() 构造函数
你可以使用 set() 构造函数来创建集合。如果传递一个序列(如列表、元组或字符串)给 set(),它会创建一个包含序列中唯一元素的新集合。

# 从列表创建集合
list_to_set = set([1, 2, 2, 3, 4, 4, 5])
print(list_to_set)

# 从元组创建集合
tuple_to_set = set((1, 2, 3, 4, 4, 5, 5, 6))
print(tuple_to_set)

# 从字符串创建集合
string_to_set = set("hello")
print(string_to_set)
#output:
{1, 2, 3, 4, 5}
{1, 2, 3, 4, 5, 6}
{'e', 'h', 'l', 'o'}

4.3 集合的增加,删除,修改

(1) 添加元素:
使用 add() 方法来添加单个元素到集合中,或者使用 update() 方法来添加多个元素

my_set = {1, 2, 3, 'Alice', 4.5}
# 添加单个元素
my_set.add(5)

# 添加多个元素
my_set.update([6, 7, 'Bob'])

print(my_set)

(2) 删除元素:
使用 remove() 或 discard() 方法来删除集合中的元素。remove() 方法会在元素不存在时抛出异常,而 discard() 方法则不会抛出异常。

# 删除已知存在的元素
my_set.remove(5)

# 尝试删除可能不存在的元素
my_set.discard('Bob')

print(my_set)
# 清空集合
my_set.clear()
print(my_set)

(3)修改集合
由于集合中的元素是唯一的,你不能直接修改某个元素。但是你可以通过删除旧元素然后添加新元素的方式间接实现修改。

# 修改元素
# 假设你想把 'Alice' 改为 'Charlie'
my_set.remove('Alice')
my_set.add('Charlie')
print(my_set)

4.4 集合的查看

直接打印或者使用in查看

5.string 字符串

5.1 特点

有序:字符串中的字符按照插入顺序排列,即字符串中的每个字符都有一个确定的位置。
不可变:字符串是不可变的,这意味着一旦创建了一个字符串,你就不能更改它的内容。如果你试图修改字符串中的某个字符,Python 会创建一个新的字符串。
异构:字符串本身只包含字符这一种数据类型。
可重复:字符串可以包含重复的字符。
可迭代对象:字符串是可迭代的对象,这意味着你可以使用循环结构(如 for 循环)来遍历字符串中的每一个字符。

5.2 字符串的创建

创建字符串非常简单。字符串是由一系列字符组成的序列,可以用单引号 (‘), 双引号 (“) 或者三引号 (”“” 或 ‘’’) 来定义、
单引号:使用 ’ 来创建字符串。
双引号:使用 " 来创建字符串。
三引号:使用 “”" 或 ‘’’ 来创建多行字符串。
空字符串:使用 ‘’ 或 “” 来创建空字符串。
特殊字符:使用转义字符 \ 来表示特殊字符。
引号嵌套:在字符串中嵌入单引号或双引号,只要它们与字符串开头的引号不同即可。

5.3 字符串的增加,删除,修改

字符是不可变的,这些增加修改删除,都是新增一个字符串
增加:
1.可以通过 + 运算符或使用 join() 方法来拼接字符串。
2.使用 join() 方法

parts = ["Hello", " ", "World"]
s = "".join(parts)
print(s)  # 输出 "Hello World"

删除:
删除字符串中的部分字符,可以使用切片和拼接的方式。

s = "Hello World"
s = s[:5] + s[6:]  # 删除 "o"
print(s)  # 输出 "Hell World"

修改:

s = "Hello World"
s = s[:5] + "there" + s[10:]
print(s)  # 输出 "Hello there"

6.Array 数组

后面完善

7.Queue 队列

后面完善

例题

from typing import Optional, List

from pydantic import BaseModel


class ConditionParams(BaseModel):
    """
    drd 节点 branch 中的 condition 结构
    """
    from_param_ref: Optional[str] = ''
    from_param_ref_path: Optional[str] = ''
    # 操作符
    op: Optional[str] = ''
    # variable
    to_param_ref: Optional[str] = ''
    to_param_ref_path: Optional[str] = ''
    to_param_type: Optional[str] = ''
    to_param_value: Optional[str] = ''
    intent_content: Optional[str] = ''


class DrdBranchParams(BaseModel):
    """
    drd 节点 branch 结构
    """
    conjunction: Optional[str] = ''
    conditions: Optional[List[ConditionParams]] = []
    # 条件目标链接 node id
    # UI 带入
    output_port_id: Optional[str] = ''
    # 在 保存 流程图时,通过 process_node_branch_output,解算得到
    output_node_ids: Optional[list[str]] = []


# 示例数据
branches = [DrdBranchParams(conjunction='and', conditions=[
    ConditionParams(from_param_ref='', from_param_ref_path='', op='', to_param_ref='', to_param_ref_path='',
                    to_param_type='', to_param_value='', intent_content='业务问题:采购订单,材料,入口')],
                            output_port_id='intent-node--1-output-1', output_node_ids=['text-node--3']),
            DrdBranchParams(conjunction='and', conditions=[
                ConditionParams(from_param_ref='', from_param_ref_path='', op='', to_param_ref='', to_param_ref_path='',
                                to_param_type='', to_param_value='', intent_content='天气问题')],
                            output_port_id='intent-node--1-output-2', output_node_ids=['text-node--1'])]

#1.转换
#给定一个包含 DrdBranchParams 对象的列表,将这些对象转换为字典,并提取每个分支的条件组合。
# [
#     {
#         'output_port_id': 'intent-node--1-output-1',
#         'output_node_ids': ['text-node--3'],
#         'conjunction': 'and',
#         'conditions': [
#             {'from_param_ref': '', 'from_param_ref_path': '', 'op': '', 'to_param_ref': '', 'to_param_ref_path': '', 'to_param_type': '', 'to_param_value': '', 'intent_content': '业务问题:采购订单,材料,入口'}
#         ]
#     },
#     {
#         'output_port_id': 'intent-node--1-output-2',
#         'output_node_ids': ['text-node--1'],
#         'conjunction': 'and',
#         'conditions': [
#             {'from_param_ref': '', 'from_param_ref_path': '', 'op': '', 'to_param_ref': '', 'to_param_ref_path': '', 'to_param_type': '', 'to_param_value': '', 'intent_content': '天气问题'}
#         ]
#     }
# ]
brancher_list = []
for branch in branches:
    branch_dict = {
        'output_port_id': branch.output_port_id,
        'output_node_ids': branch.output_node_ids,
        'conjunction': branch.conjunction,
        'conditions': [condition.dict() for condition in branch.conditions]
    }
    brancher_list.append(branch_dict)
# print(brancher_list)

#2.条件统计
#给定一个包含 DrdBranchParams 对象的列表,统计每个 intent_content 的出现次数。
# {
#     '业务问题:采购订单,材料,入口': 2,
#     '天气问题': 1
# }
intent_counts = {}
for branch in branches:
    for condition in branch.conditions:
        intent_counts[condition.intent_content] = intent_counts.get(condition.intent_content, 0) + 1
# print(intent_counts)


# 3.条件筛选
# target_intent_content = '业务问题:采购订单,材料,入口'
# 给定一个包含 DrdBranchParams 对象的列表,筛选出 intent_content 为特定值的分支。
# [
#     {
#         'output_port_id': 'intent-node--1-output-1',
#         'output_node_ids': ['text-node--3'],
#         'conjunction': 'and',
#         'conditions': [
#             {'from_param_ref': '', 'from_param_ref_path': '', 'op': '', 'to_param_ref': '', 'to_param_ref_path': '', 'to_param_type': '', 'to_param_value': '', 'intent_content': '业务问题:采购订单,材料,入口'}
#         ]
#     },
#     {
#         'output_port_id': 'intent-node--1-output-3',
#         'output_node_ids': ['text-node--4'],
#         'conjunction': 'and',
#         'conditions': [
#             {'from_param_ref': '', 'from_param_ref_path': '', 'op': '', 'to_param_ref': '', 'to_param_ref_path': '', 'to_param_type': '', 'to_param_value': '', 'intent_content': '业务问题:采购订单,材料,入口'}
#         ]
#     }
# ]
target_list = []
target_intent = '业务问题:采购订单,材料,入口'
for branch in branches:
    # for condition in branch.conditions:
    #     if condition.intent_content == target_intent:
    if any(target_intent == condition.intent_content for condition in branch.conditions):
            target_dict = {
                'output_port_id': branch.output_port_id,
                'output_node_ids': branch.output_node_ids,
                'conjunction': branch.conjunction,
                'conditions': [condition.dict() for condition in branch.conditions]
            }
            target_list.append(target_dict)
# print(target_list)

#4.列表推导式的联系
#4.1 列表推导式 提取所有意图内容 (Intent Content)
result1 = [ condition.intent_content for branch in branches for condition in branch.conditions ]
# 元组推导式,元组的定义要加 tuple()
result2 = tuple( condition.intent_content for branch in branches for condition in branch.conditions )
# 注意元组和生成器对象的区别
result3 = ( condition.intent_content for branch in branches for condition in branch.conditions )
# print((result3)) # 直接输出是未被消耗的生成器,需要迭代的时候执行 <generator object <genexpr> at 0x0000018A1F7E3E60>
# 集合推导式
result4 = set( condition.intent_content for branch in branches for condition in branch.conditions )
print(result4)
#4.2创建意图内容到分支ID的映射
dict_result = {condition.intent_content : branch.output_port_id for branch in branches for condition in branch.conditions}
# print(dict_result)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵钱孙李的赵

感谢各位衣食父母

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值