Python | 第九章 | 排序和查找

P90 集合课堂练习 2024/9/28

一、集合生成式

  1. 集合生成式就是"生成集合的公式"
  2. 基本语法:
python 复制代码
{集合元素的表达式for 自定义变量 in 可迭代对象}

实例(set_create.py)说明:
{ ele * 2 for ele in range(1,5)}==>得到集合含有2,4,6,8这四个元素,
但是集合是无序的,所以不能保证元素的顺序一定是2,4,6,8

思考题:
{ ele + ele for ele in"韩顺平"}=得到集合==> 

结果

python 复制代码
set1 = {ele * 2 for ele in range(1, 5)}
print("set1:", set1)  # {8, 2, 4, 6}

set2 = {ele + ele for ele in "韩顺平"}
print("set2:", set2)

说明 :大家注意观察:集合生成式和列表生成式的区别就在于,集合生成式使用{},而列表生成式使用[]

二、课堂练习

python 复制代码
# @Author :zjc
# @File   :026_set_exercise.py
# @Time   :2024/9/28 17:12

# 1、用三个集合表示三门学科的选课学生姓名(一个学生可以同时选多门课)
s_history = {"小明", "张三", "李四", "王五", "Lily", "Bob"}
s_politic = {"小明", "小花", "小红", "二狗"}
s_english = {"小明", "Lily", "Bob", "Davil", "李四"}

# 1. 求选课学生总共有多少人
"""
    思路分析:
    1. 对三个集合求并集【自动去重】
    2. 对新的集合求len()
"""
student01 = s_history | s_politic | s_english
# student01 = s_history.union(s_politic, s_english)
print(f"选课学生总共有多少人:{len(student01)}")

# 2. 求只选了第一个学科的学生数量和学生名字
"""
    思路分析:
    1. 即求出只在s_history学院
    2. 使用差集即可 s_history - s_politic - s_english
"""
print(f"只选了第一个学科的学生数量{len(s_history - s_politic - s_english)}"
      f"学生姓名{s_history - s_politic - s_english}")

# 3. 求只选了一门学科的学生数量和学生名字
"""
    1. 求出只选了history的学生
    2. 求出只选了politic的学生
    3. 求出只选了english的学生
    4. 然后求出并集集合
"""

# 1、 求出只选了history的学生
s1 = s_history - s_politic - s_english
# 2、求出只选了politic的学生
s2 = s_politic - s_english - s_history
# 3、 求出只选了english的学生
s3 = s_english - s_history - s_politic
print(f"只选了一门学科的学生数量{len(s1 | s2 | s3)}和学生名字{s1 | s2 | s3}")

# 4. 求选了三门学科的学生数量和学生名字
"""
    思路分析:
    1. 求出即在s_politic 又在s_history还在s_english中的
    2. 就是对三个集合求交集
"""

print(f"选了三门学科的学生数量{len(s_history & s_politic & s_english)}"
      f"和学生名字{s_history & s_politic & s_english}")

P91 字典基本使用 2024/9/29

参考文档https://docs.python.org/zh-cn/3.11/tutorial/datastructures.html#dictionaries

一、需求引出

思路分析 :

1、目前这种需求是:通过xx查询yy的需求

2、在编程中,我们通常称为基于Key查询Value场景需求,是经常遇到的,是一种映射关系

3、而前面学习的列表、元组、集合都是一种单值存储,处理映射关系就不方便了

4、解决方案->字典(dict)

二、基本介绍

  1. 字典(dict,完整的单词是dictionary)也是一种常用的 Python 数据类型,其他语言可能把字典称为联合内存联合数组
  2. 字典是一种映射类型 ,非常适合处理通过xx查询yy 的需求,这里的xx我们称为Key(键/关键字),这里的yy 我们称为Value(值),即Key----Value的映射关系
  3. 龟叔为什么把这种映射类型,命名为字典,这个很有意思,示意图:

三、字典的定义

  • 创建一个字典,只要把逗号分隔的不同的元素,用括起来即可,存储的元素是一个个的:键值对,示例:

dict_a= {key1:value, key2:value, key3:value... .}

-通过key取出对应的value语法:

字典名[key]---->dict_a[key1]

  • 字典使用基本案例
python 复制代码
# 字典的基本使用案例
# 定义字典:键值对
tel = {'jack': 4098, 'tom': 4139}
print(f"dict_tel: {tel}类型: {type(tel)}")  # 查询jack 的tel <class 'dict'>
# 保证jack是可以查询到的
print("jack的tel:", tel['jack'])  # 4098

四、注意事项和细节

  1. 字典的Key(关键字)通常是字符串数值 , Value可以是任意数据类型
python 复制代码
dict_a = {
    # 值为列表
    "jack": [100, 200, 300],
    # 值为元组
    "mary": (10, 20, "hello"),
    # 值为集合
    "nono": {"apple", "pear"},
    # 值为 字符串
    "smith": "计算机老师",
    # 值为 字典
    "周星驰": {
        "性别": "男",
        "age": 18,
        "地址": "香港"
    },
    "key1": 100,
    "key2": 9.8, 
    "key3": True
}

print(f"dict_a: {dict_a}类型:{type(dict_a)}")
  1. 字典不支持索引,会报KeyError
python 复制代码
print(dict_a[0]) # 报错
  1. 既然字典不支持索引,所以对字典进行遍历不支持while,只支持for,注意直接对字典进行遍历,遍历得到是key。
python 复制代码
# 3、既然字典不支持索引,所以对字典进行遍历不支持while,只支持for
dict_b = {'one': 1, 'two': 2, 'three': 3}
# 遍历方式1-依次取出key, 再通过dict[key]取出对应的value

print("----------遍历方式1----------")
for key in dict_b:
    print(f"key:{key} value:{dict_b[key]}")

# 遍历方式2-依次取出value
# 仅取出值:
print("----------遍历方式2----------")
for value in dict_b.values():
    print(f"value:{value}")

# 遍历方式3-依次取出key-value
# 一次性取出键和值:
print("----------遍历方式3----------")
for k,v in dict_b.items():
    print(f"k :{k},va:{v}")
  1. 创建空字典可以通过{},或者dict()
python 复制代码
# 4、创建空字典可以通过{},或者dict()
dict_c = {}
dict_d = dict()
print(f"dict_c: {dict_c}类型:{type(dict_c)}")
print(f"dict_d: {dict_d}类型:{type(dict_d)}")
  1. 字典的key必须是唯一的,如果你指定了多个相同的key,后面的键值对套覆盖前面的
python 复制代码
dict_e = {'one': 1, 'two': 2, 'three ': 3, 'two': 200}
print(f"dict_e: {dict_e}")  # {'one': 1, 'two': 200, 'three ': 3}

P92 字典常用操作 2024/9/30

一、常用操作一览

案例演示

python 复制代码
# @Author :zjc
# @File   :029_dic_operations.py
# @Time   :2024/9/30 15:58

"""
    演示字典的常用操作
    { "one": 1,"two" : 2,"three" : 3}
"""
# 定义字典
dict_a = {"one": 1, "two": 2, "three": 3}

# 1 len(d):返回字典d 中的项数
print(f"dict_a 的元素个数是:{len(dict_a)}")

# 2 d[key]:返回d中以 key 为键的项。如果映射中不存在 key 则会引发keyError
print("key为three对应的value : ", (dict_a['three']))  # 3

# 3 d[key] = value:将d[key] 设为 value,如果key已经存在,则是修改value,
# 如果key没有存在,则是增加 key-value,注意会直接修改原来的字典-示意图
# 修改需求:修改key = 'one'对应的value为第一
dict_a["one"] = "第一"  # 相当于之前的one被替换成"第一"
print(f"dic_a:{dict_a}")

# 添加需求:增加key为'four' value为4
dict_a["four"] = 4
print(dict_a)

# 4 del d[key]:将d[key] 从d中移除。如果映射中不存在key 则会引发KeyError
# 需求删除key为'four'的元素
del dict_a["four"]
print(f"dict_a: {dict_a}")

# 5 pop(key, default]) :
# 如果key存在于字典中则将其移除并返回其值,否则返回 default。
# 如果default未给出且 key不存在于字典中,则会引发KeyError
# 需求:将key为'one'的值返回,并将该元素从字典移除
# val = dict_a.pop("one~","哈哈") # 会返回默认"哈哈"
val = dict_a.pop("one")  # 会移除元素并且返回其值
print(f"val: {val}")
print(f"dict_a: {dict_a}")

# 6 keys():返回字典所有的key
dict_a_keys = dict_a.keys()
print(f"dict_a_keys: {dict_a_keys}类型{type(dict_a_keys)}")  # <class 'dict_keys'>
# 同样也可以取出来 for循环
for k in dict_a_keys:
    print("k->", k)

# 7 key in d:如果d中存在键key则返回True,否则返回 False
# 需求:判断字典中是否有 key 'two '
print("two" in dict_a)  # True

# 8 clear():移除字典中的所有元素#需求:将字典清空
dict_a.clear()
print(f"dict_a: {dict_a}")

二、字典生成式

1、看一个具体的需求给出了如下两个列表:

python 复制代码
books =["红楼梦","三国演义","西游记","水浒传"]
authors =["曹雪芹","罗贯中","吴承恩","施耐庵"]

生成对应的字典:
{'红楼梦':'曹雪芹','三国演义':'罗贯中','西游记'":'吴承恩','水浒传':'施耐庵'}

2、内置函数zip()

说明 :zip()可以将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,返回由这些元组组成的列表

字典生成式基本语法
字典key的表达式:字典value的表达式 for 表示key的变量,表示value的变量 in zip(可迭代对象,可迭代对象)}

python 复制代码
# 实例说明:
books = ["红楼梦", "三国演义", "西游记", "水浒传"]
authors = ["曹雪芹", "罗贯中", "吴承恩", "施耐庵"]
dict_a = {book: author for book, author in zip(books, authors)}
print("dict_book", dict_a)

# 思考题1:
str1 = "韩顺平"
dict_b = {ele1: ele2 * 2 for ele1, ele2 in zip(str1, str1)}
print("str1:", dict_b)

# 思考题2:
# 给出两个列表:
english_list = ["red", "black", "yellow", "white"]
chinese_list = ["红色", "黑色", "黄色", "白色"]
# 生成一个字典:
# {'红色': 'RED', '黑色': 'BLACK', '黄色': 'YELLOW', '白色': 'WHITE'}
dict_c = {ele1:ele2.upper() for ele1,ele2 in zip(chinese_list,english_list)}
print(dict_c)

P93 字典课堂练习 2024/9/30

一、课堂练习

  • 解决之前的需求:
    • 一个公司有多个员工,请使用合适的数据类型保存员工的信息(比如员工号、年龄、名字、入职时间、薪水等),
      • 1、员工号是入职时分配的,唯一不重复
python 复制代码
# @Author :zjc
# @File   :031_dict_exercise.py
# @Time   :2024/9/30 17:20

clerks = {"0001": {"age": 20,
                   "name": "贾宝玉",
                   "entry_time": "2011-11-11",
                   "sal": 12000
                   },

          "O002": {"age": 21,
                   "name": "薛宝钗",
                   "entry_time": "2015-12-12",
                   "sal": 10000
                   },

          "0010": {"age": 18,
                   "name": "林黛玉",
                   "entry_time": "2018-10-10",
                   "sal": 20000
                   }
          }
# 2)通过员工号(0010),可以查询到员工的信息
print(f"员工号为0010的信息为:"
      f"名字:{clerks["0010"]["name"]} "
      f"年龄:{clerks["0010"]["age"]}"
      f"入职时间:{clerks["0010"]["entry_time"]} "
      f"薪水:{clerks["0010"]["sal"]}")

# 3)可以根据需要,可以动态的增加、删除员工,请演示添加和删除一个员工
# 增加:(员工号:0020,年龄:30,名字:老韩,入职时间:2020-08-10,薪水: 6000)
clerks["0020"] = {
    "age": 30,
    "name": "老韩",
    "entry_time": "2020-8-10",
    "sal": 6000
}
print(clerks)
# 删除:0001号员工
del clerks["0001"]
print("-" * 60)
print(clerks)

# 4)可以根据需要,可以修改员工的信息(比如年龄、名字、入职时间、薪水等),
# 请演示修改一个员工信息修改员工号为0020的,
# 名字:韩顺平,入职时间: 1999-10-10,薪水在原来的基础上增加10%
clerks["0020"]['name'] = '韩顺平'
clerks["0020"]['entry_time'] = '1999-10-10'
clerks["0020"]['sal'] += clerks["0020"]['sal'] * 0.1
print(clerks)

# 5)要求:遍历所有员工,把所有员工的薪水,在原工资的基础上,增加20%
keys = clerks.keys()
for key in keys:
    clerks[key]['sal'] += clerks[key]['sal'] * 0.2
print("-" * 60)
print("clerks", clerks)

# 6)按照如下格式输出所有员工信息
# 员工号为??的信息如下年龄:??名字:??入职时间:??薪水:??
for key in keys:
    print(f"员工号为{key}的信息如下 "
          f"年龄:{clerks[key]['age']}"
          f"名字:{clerks[key]['name']}"
          f"入职时间:{clerks[key]['entry_time']}"
          f"薪水:{clerks[key]['sal']}")

print("-" * 60)

for key in keys:
    # 取出key的值,就是每个员工对应的信息,每个员工对应的所有信息就是第一个键的值
    # 通过key得到员工的信息(字典)
    clerks_info = clerks[key]
    print(f"员工号为{key}的信息如下 "
          f"年龄:{clerks_info['age']}"
          f"名字:{clerks_info['name']}"
          f"入职时间:{clerks_info['entry_time']}"
          f"薪水:{clerks_info['sal']}")

P94 数据容器特点比较及小结 2024/10/1

一、数据容器特点比较

二、通用序列操作

  • 大多数序列类型,包括可变类型和不可变类型都支持下表中的操作:

三、通用转换操作

  • 容器转用操作一览
  • 案例演示
python 复制代码
# @Author :zjc
# @File   :032_container_convert.py
# @Time   :2024/10/1 20:43

str_a = "hello"
list_a = ["jack", "tom", "mary"]
tuple_a = ("hsp", "tim")
set_a = {"red", "black"}
dict_a = {"O001": "小倩", "O002": "黑山老妖"}
# 1. list([iterable]):
# iterable 可以是序列、支持迭代的容器或其它可迭代对象,#也就是将指定的容器转成列表
print("-" * 60)
print(f"str_a转成list: {list(str_a)}")  # ['h', 'e', 'l', 'l', 'o']
print(f"tuple_a转成list: {list(tuple_a)}")  # ['hsp', 'tim']
print(f"set_a转成list: {list(set_a)}")  # ['black', 'red']
print(f"dict_a转成list: {list(dict_a)}")  # ['O001', 'O002']

# 2. str(容器)∶将指定的容器转成字串(相当于整体都转了,包含括号)
print("-" * 60)
print(f"list_a转成str: {str(list_a)}类型: {type(str(list_a))}")
print(f"tuple_a转成str->{str(tuple_a)}类型:{type(str(tuple_a))}")
print(f"set_a转成str->{str(set_a)}类型: {type(str(set_a))}")
print(f"dict_a转成str->{str(dict_a)}类型->{type(str(dict_a))}")

# 3. tuple([iterable]):
# iterable 可以是序列、支持迭代的容器或其他可迭代对象,也就是将指定容器转成元组
print("-" * 60)
print(f"str_a转成tuple->{tuple(str_a)}")
print(f"list_a转成tuple->{tuple(list_a)}")
print(f"set_a转成tuple->{tuple(set_a)}")
print(f"dict_a转成tuple->{tuple(dict_a)}")

# 4. set([iterable]):
# iterable可以是序列、支持迭代的容器或其他可迭代对象,#也就是将指定的容器转成集合
print("-" * 60)
print(f"str_a转成set: {set(str_a)}")  # 自动去重
print(f"st_a转成set: {set(list_a)}")
print(f"tuple_a转成set: {set(tuple_a)}")
print(f"dict_a转成set: {set(dict_a)}")

四、其他操作说明

P95 传参机制和分享 2024/10/2

一、list、tuple、set和dict传参机制

  1. 看一个案例,分析结果是什么?[列表]
python 复制代码
# ----------------list--------------------------------
def f1(my_list):
    print(f"2:f1() my_list: {my_list}地址是:{id(my_list)}")
    my_list[0] = "jack"
    print(F"3:f1() my_list: imy_list]地址是:{id(my_list)}")


# 测试
my_list = ["tom", "mary", "hsp"]
print(f"1:my_list: {my_list}地址是:{id(my_list)}")
# 调用函数
f1(my_list)
print(f"4:mly _五ist: {my_list}地址是:{id(my_list)}")
  • 列表结论:在函数中修改列表中的值会改变原列表的值,输出的地址都是一样的。
  1. 元组-tuple
python 复制代码
# tuple 元组
def f2(my_tuple):
    print(f"②f2() my_tuple: {my_tuple}地址是: {id(my_tuple)}")
    # 不能修改
    # my_tuple[0] = "red "
    print(f"③f2() my_tuple: {my_tuple}地址是:{id(my_tuple)}")


# 测试
my_tuple = ("hi", "ok", "hello")
print(f"①my_tuple: {my_tuple}地址是:{id(my_tuple)}")
f2(my_tuple)
print(f"④my_tuple: {my_tuple}地址是:{id(my_tuple)}")
  1. 集合set()是可变数据类型,执行机制和列表一致
python 复制代码
def f3(my_set):
    print(f"②f3() my Tset: {my_set}地址是: {id(my_set)}")
    my_set.add("<<红楼梦>>")
    print(f"③f3() my_set: {my_set}地址是:{id(my_set)}")


# 测试
my_set = {"水浒", "西游", "三国"}
print(f"①my_set: {my_set}地址是:{id(my_set)}")
f3(my_set)
print(f"④my_set: {my_set}地址是:{id(my_set)}")
  1. 字典dict()
python 复制代码
def f4(my_dict):
    print(f"②f4( ) my_dict: {my_dict}地址是:{id(my_dict)}")
    my_dict['address'] = "兰若寺"
    print(f"③f4() my_dict: {my_dict}地址是:{id(my_dict)}")


# 测试
my_dict = {"name": "小倩", "age": 18}
print(f"①my_dict: {my_dict}地址是:{id(my_dict)}")
f4(my_dict)
print(f"my_dict: {my_dict}地址是:{id(my_dict)}")

二、小结

  1. python数据类型主要有整数int/浮点数float/字符串str/布尔值bool/元组tuple/ 列表list/字典dict/集合set,数据类型分为两个大类,一种是可变数据类型 ;一种是不可变数据类型

  2. 可变数据类型和不可变数据类型

可变数据类型 :当该数据类型的变量的值发生了变化,如果它的内存地址不变 ,那么这个数据类型就是可变数据类型
不可变数据类型 :当该数据类型的变量的值发生了变化,如果它的内存地址改变了,那么这个数据类型就是不可变数据类型

  1. Python数据类型

不可变数据类型:数值类型(int、float)、bool(布尔)、string(字符串)、tuple(元组)

可变数据类型: list(列表)、set(集合)、dict(字典)

三、本章回顾

P96 冒泡排序 2024/10/2

一、基本介绍

  • 排序是将多个数据,按照指定的顺序进行排列的过程

  • 排序的分类

排序算法有:

一、冒泡排序

二、选择排序

三、插入排序

四、希尔排序

六、快速排序

七、堆排序

  • 介绍

冒泡排序(Bubble Sorting〉的基本思想是:重复地走访需要排序的元素列表,依次比较两个相邻的元素,如果顺序(如从大到小或从小到大)错误就交换它们的位置。重复地进行直到没有相邻的元素需要交换,则元素列表排序完成。

在冒泡排序中,值最大(或最小)的元素会通过交换慢慢"浮"到元素列表的"顶端"。就像"冒泡"一样,所以被称为冒泡排序

  • 冒泡排序法案例

下面我们举一个具体的案例来说明冒泡法,列表:[24,69,80,5,13]有5个元素,使用冒泡排序法将其排成一个从小到大的有序列表

思路分析

  • Python中使用sort方法可以完成快速排序:
python 复制代码
# 老韩说明,如果只是完成排序功能,我们可以直接使用ist的方法sort,如下

num_list = [24, 69, 80, 57, 13]
# .center可以调整输出宽度
print("排序前".center(32, "-"))
print(f"num_list: {num_list}")

# 使用sort方法完成排序
num_list.sort()
print("排序后".center(32, "-"))
print(f"num_list: {num_list}")
  • 使用冒泡排序,自己完成排序,了解底层原理,深刻理解(以后遇到不同业务,需要定制排序,也能处理)
  • 1、先把代码写死"先死后活"
python 复制代码
num_list = [24, 69, 80, 57, 13, 11, 900,-10,9]
# .center可以调整输出宽度
print("排序前".center(32, "-"))
print(f"num_list: {num_list}")
# 使用冒泡排序,自己完成排序,了解底层原理,深刻理解(以后遇到不同业务,需要定制排序,也能处理)

# 定义函数:完成排序
def bubble_sort(my_lsit):
    """
    功能:对传入的列表排序-顺序从小到大
    :param my_lsit:传入的列表
    :return:无
    """
    """
        第一轮排序:把最大的数放到最后的位置
        第1次比较:[24,69,80,57,13]
        第2次比较:[24,69,80,57,13]
        第3次比较:[24,69,57,80,13]
        第4次比较:[24,69,57,13,80]
    """
    # j变量控制比较的次数,同时可以作为比较元素的下标
    for j in range(0, 4):  # [0,1,2,3]
        # 如果前面的元素大于后面的元素就交换
        if my_lsit[j] > my_lsit[j + 1]:
            my_lsit[j], my_lsit[j + 1] = my_lsit[j + 1], my_lsit[j]

    print("第一轮排序后的结果my_lsit", my_lsit)

    """
    第二轮排序:把第二大数放到倒数第二的位置
    第1次比较:[24,69,57,13,80]
    第2次比较:[24,57,69,13,80]
    第3次比较:[24,57,13,69,80]
    """

    # j变量控制比较的次数,同时可以作为比较元素的下标
    for j in range(0, 3):  # [0,1,2]
        # 如果前面的元素大于后面的元素就交换
        if my_lsit[j] > my_lsit[j + 1]:
            my_lsit[j], my_lsit[j + 1] = my_lsit[j + 1], my_lsit[j]

    print("第二轮排序后的结果my_lsit", my_lsit)


    """
    第三轮排序:把第三大数放到倒数第三的位置
    第1次比较:[24,57,13,69,80]
    第2次比较:[24,13,57,69,80]
    """
    # j变量控制比较的次数,同时可以作为比较元素的下标
    for j in range(0, 2):  # [0,1,2]
        # 如果前面的元素大于后面的元素就交换
        if my_lsit[j] > my_lsit[j + 1]:
            my_lsit[j], my_lsit[j + 1] = my_lsit[j + 1], my_lsit[j]

    print("第三轮排序后的结果my_lsit", my_lsit)

    """
    第四轮排序:把第四大数放到倒数第四的位置
    第1次比较:[13,24,57,69,80]
    """
    # j变量控制比较的次数,同时可以作为比较元素的下标
    for j in range(0, 1):  # [0,1,2]
        # 如果前面的元素大于后面的元素就交换
        if my_lsit[j] > my_lsit[j + 1]:
            my_lsit[j], my_lsit[j + 1] = my_lsit[j + 1], my_lsit[j]

    print("第四轮排序后的结果my_lsit", my_lsit)

bubble_sort(num_list)
  • 用两层for循环优化
python 复制代码
num_list = [24, 69, 80, 57, 13, 11, 900,-10,9]
# .center可以调整输出宽度
print("排序前".center(32, "-"))
print(f"num_list: {num_list}")
def bubble_sort(my_lsit):
    """
    功能:对传入的列表排序-顺序从小到大
    :param my_lsit:传入的列表
    :return:无
    """
    """
        通过分析,我们发现每轮的比较逻辑是一样的
        我们只需要考虑变化部分即可,使用外层for循环来解决
    """
    for i in range(0,4):
        for j in range(0, 4-i):  # [0,1,2]
            # 如果前面的元素大于后面的元素就交换
            if my_lsit[j] > my_lsit[j + 1]:
                my_lsit[j], my_lsit[j + 1] = my_lsit[j + 1], my_lsit[j]

        print(f"第{i+1}轮排序后的结果my_lsit", my_lsit)

bubble_sort(num_list)
  • "后活",改变列表元素个数,使用len()控制
python 复制代码
num_list = [24, 69, 80, 57, 13, 11, 900,-10,9]
# .center可以调整输出宽度
print("排序前".center(32, "-"))
print(f"num_list: {num_list}")

# 使用冒泡排序,自己完成排序,了解底层原理,深刻理解(以后遇到不同业务,需要定制排序,也能处理)

# 定义函数:完成排序
def bubble_sort(my_lsit):
    """
    功能:对传入的列表排序-顺序从小到大
    :param my_lsit:传入的列表
    :return:无
    """
    """
        通过分析,我们发现每轮的比较逻辑是一样的
        我们只需要考虑变化部分即可,使用外层for循环来解决
    """

    # i变量来控制多少轮排序len
    for i in range(0, len(my_lsit) - 1):
        for j in range(0, len(my_lsit) - 1 - i):  # [0,1,2]
            # 如果前面的元素大于后面的元素就交换
            # 如果是从小到大是:>;从大到小 <
            if my_lsit[j] > my_lsit[j + 1]:
                my_lsit[j], my_lsit[j + 1] = my_lsit[j + 1], my_lsit[j]

        print(f"第{i + 1}轮排序后的结果my_lsit", my_lsit)


bubble_sort(num_list)

print("排序后".center(32, "-"))
print(f"num_list: {num_list}")

P97 顺序查找 2024/10/3

一、基本介绍

二、顺序查找案例

  • 有一个列表:[白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王]

猜名字游戏:从键盘中任意输入一个名称,判断列表中是否包含此名称【顺序查找】

要求:如果找到了,就提示找到,并给出下标值

  • 如果只是完成一个查找,使用list.index就可以完成
python 复制代码
# 老韩说明,如果只是完成查找功能,我们可以直接使用ist的方法index,如下
names_list = ["白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"]
find_name = "金毛狮王"
print(names_list.index("金毛狮王")) # 1
  • 除了掌握系统提供的index(),程序员也应当掌握一些基本的查找方法(以后遇到不同业务,需要定制排序,也能处理)
python 复制代码
names_list = ["白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"]


def seq_search(my_list, find_val):
    """
    功能:顺序查找指定的元素
    :param my_list:传入的列表(即要查找的列表)
    :param find_val:要查找的值/元素
    :return:如果查找到就返回对应的索引下标,否则返回-1
    """
    """
    思路分析:
    1. 对列表进行遍历,如果找到了,则返回对应下标
    2. 如果遍历结束,没有找到,则返回-1
    """
    find_index = -1
    # 遍历
    for i in range(len(my_list)):
        # 如果当前的元素就是查找的值就返回当前的索引
        if my_list[i] == find_val:
            print(f"恭喜找到对应的值{find_val}下标是{i}")
            find_index = i
            break  # 退出for循环

    else:
        print(f"没有找到对应的值{find_val}")

    return find_index


print(seq_search(names_list, "金毛狮王"))
  • 思考题

如果一个列表中有多个要查找的元素/值,比如前面的列表有两个金毛狮王,请思考,怎样才能把满足查询条件的元素的下标,都返回.

python 复制代码
# 编写顺序查找函数seq_search
names_list = ["白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王","金毛狮王","金毛狮王"]
def seq_search2(my_list, find_val):
    # 定义一个空列表
    find_index = []
    # 遍历
    for i in range(len(my_list)):
        # 如果当前的元素就是查找的值就保存到find_index
        if my_list[i] == find_val:
            # 将找到的下标,添加到find_index
            find_index.append(i)

    return find_index


res_index = seq_search2(names_list, "金毛狮王")
print(res_index)

P98 二分查找 2024/10/3

一、查找案例

  • 二分查找案例

请对一个列表(元素是从小到大排序的 )进行二分查找[1,8,10,89,1000,1234]

输入一个数看看该列表是否存在此数,并且求出下标,如果没有就返回-1

  • 思路分析
python 复制代码
# @Author :zjc
# @File   :03_binary_search.py
# @Time   :2024/10/3 17:36
"""
    二分查找的思路分析
    前提:该列表是一个排好序的列表(为了分析方便,就以从小到大的列表为例分析
    1.找到列表的中间数 mid_val和find_val比较
    2.如果mid_val > find_val ,则到 mid_val的左边查找
    3.如果mid_val < find_val ,则到 mid_val的右边查找
    4.如果mid_val =  find_val ,则到找到,返回对应的下标即可
    5.不断的重复1-4步骤,这里就是不断的折半,使用while
    6.如果while 结束,都没有找到,说明ind_val 没有在列表
"""
# 查找的列表
num_list = [1, 8, 10, 89, 1000, 1234]


# 编写二分查找的函数
def binary_search(my_list, find_val):
    """
    功能:完成二分查找
    :param my_list: 要查找的列表(有顺序的)
    :param find_val:要查找的元素/值
    :return:返回对应的下标,如果没有找到返回-1
    """
    left_index, right_index = 0, len(my_list) - 1
    # 定义找到数的下标
    find_index = -1
    # 使用while循环不断的折半比较满足条件:left_index <= right_index
    while left_index <= right_index:
        # 中间数的下标/索引
        mix_index = (left_index + right_index) // 2
        # 1.如果mid_val > find_val ,则到 mid_val的左边查找
        # 2.在左边查找就相当于移动到中间数的 索引-1
        if my_list[mix_index] > find_val:
            right_index = mix_index - 1
        # 2.在右边查找就相当于移动到中间数的 索引+1
        elif my_list[mix_index] < find_val:
            left_index = mix_index + 1
        else:  # 相等
            find_index = mix_index
            break  # 找到就退出while循环

    return find_index


# 测试:
res_index = binary_search(num_list, 1)
if res_index == -1:
    print("没有找到该数")
else:
    print(f"找到数,对应的下标{res_index}")

二、二分查找的细节

  1. 二分查找的前提是该列表已经是一个排好序的列表(从小到大或者从大到小)

  2. 排列的顺序是从小到大还是从大到小,会影响二分查找的代码逻辑[举例说明]

  3. 把列表改成从大到小排序,看看是否还能正确盘找?又应当如何修改

python 复制代码
# 将大小更换一下
if my_list[mix_index] < find_val:
# 同样的操作
elif my_list[mix_index] > find_val:

P99 本章作业 2024/10/4

一、练习

  1. 随机生成10个整数(1-100的范围)保存到列表,使用冒泡排序,对其进行从大到小排序
python 复制代码
# @Author :zjc
# @File   :04_homework01.py
# @Time   :2024/10/4 18:50

import random

my_list = []
for i in range(0, 10):
    my_list.append(random.randint(1, 100))
# my_list.sort()
print("排序前:", my_list)


def list_sort(my_list):
    for i in range(len(my_list) - 1):
        for j in range(len(my_list) - 1 - i):
            if my_list[j] < my_list[j + 1]:
                my_list[j], my_list[j + 1] = my_list[j + 1], my_list[j]


list_sort(my_list)
print("排序后:", my_list)
  1. 在第1题的基础上,使用二分查找,查找是否有8这个数,如果有,则返回对应的下标,如果没有,返回-1
    老韩提示:注意这里要查找的列表是从大到小...
python 复制代码
def binary_search(my_list, find_val):
    left_index, right_index = 0, len(my_list) - 1
    find_index = -1
    while left_index <= right_index:
        mid_index = (left_index + right_index) // 2
        if my_list[mid_index] < find_val:
            right_index = mid_index - 1
        elif my_list[mid_index] > find_val:
            left_index = mid_index + 1
        else:
            find_index = mid_index
            break
    return find_index


res_index = binary_search(my_list, 99)
if res_index == -1:
    print("没有找到!")
else:
    print("查找数的索引是",res_index)
相关推荐
java1234_小锋2 分钟前
[免费]基于Python的深度学习豆瓣电影数据可视化+情感分析推荐系统(Flask+Vue+LSTM+scrapy)【论文+源码+SQL脚本】
python·信息可视化·flask·电影数据可视化
交换机路由器测试之路25 分钟前
交换机路由器基础(四)--TCPIP四层模型及常见协议技术
网络·网络协议·路由器·交换机·tcp/ip模型
老蒋新思维27 分钟前
借刘润之智,在 IP+AI 时代构筑战略 “增长方舟”|创客匠人
大数据·网络·人工智能·网络协议·tcp/ip·创客匠人·知识变现
多多*31 分钟前
一个有 IP 的服务端监听了某个端口,那么他的 TCP 最大链接数是多少
java·开发语言·网络·网络协议·tcp/ip·缓存·mybatis
网硕互联的小客服33 分钟前
Windows2008 如何禁用FSO?
运维·服务器·网络·windows·安全
打码人的日常分享39 分钟前
智慧楼宇资料合集,智慧城市智慧社区智慧园区
大数据·网络·人工智能
PieroPc1 小时前
一个基于Python Streamlit sqlite3 的销售单管理系统,提供商品管理、客户管理、销售单管理及打印,和应收对账单等功能
python·oracle·sqlite·streamlit
月下倩影时1 小时前
视觉进阶篇—— PyTorch 安装
人工智能·pytorch·python
普普通通的南瓜1 小时前
网站提示 “不安全”?免费 SSL 证书一键解决
网络·数据库·网络协议·算法·安全·iphone·ssl
上线就吃代码1 小时前
【等保测评】数据库数据库配置have_ssl参数为yes
服务器·数据库·ssl