Python基础语法(3)

基础语法(3)

列表与元组

变量就是内存空间,用来表示/存储数据~~~

如果表示数据少,直接定义几个变量就行了

也有的时候,要表示的数据比较多

Python中,列表和元组,就是这样的机制,可以用一个变量来表示很多个数据(类似于其他编程语言里面的数组)

列表与元组大多数功能是差不多的,但是有一个功能有非常明显的区别

列表是可变的:创建好了之后,随时能改

元组是不可变得:创建好之后,改不了.要想改,只能丢弃旧的,搞个新的

列表的各种操作

1.创建与访问元素

# 列表创建
# 1. 直接使用字面值来创建
#   [] 就表示一个空的列表
a = []
print(type(a))

# 2. 使用 list() 来创建
a = list()
print(type(a))

# 3. 可以在创建列表的时候,在[]中指定列表的初始值
# 元素之间采用 , 来分割
a = [1, 2, 3, 4]
print(a)

# 4. 可以在同一个列表里放不同类型的变量
# C++/Java中要求一个数组中只能存放相同类型的数据
a = [1, 'hello', True, [4,5,6]]
print(a)

# 5. 通过下标访问列表元素---用到下标访问操作符:[]
# 所以同样是 [] , 在不同场景下有着不同的含义
# 注意下标是从0开始的(C语言开始,后世的各个语言下标都是从0开始的)
a = [1, 2, 3, 4]
print(a[2])

# 6.使用下标修改列表元素
a = [1, 2, 3, 4]
a[2] = 100
print(a[2])

# 7. 超出下标有效范围,就会出现异常(下标有效范围为 0 到 长度 - 1)
# a = [1, 2, 3, 4]
# a[100] = 0
# print(a)

# 8. 使用内建函数 len 获取列表长度(元素个数),和字符串类似
# len 可以传字符串,列表,元组,字典,自定义的类---  => Python 动态类型特点
a = [1, 2, 3, 4]
print(len(a))

# 9. Python中的下标还可以写成负数
# 例如 写成 -1 ,等价于 len(a) - 1
a = [1, 2, 3, 4]
print(a[len(a) - 1])
# -1 就是倒数第一个元素
print(a[-1])

2.切片操作

# 1. 切片操作
# 下标访问是一次取一个元素,而切片操作则是一次取出一组连续的元素,相当于得到一个子列表
a = [1, 2, 3, 4]
print(a[1:3])
# 切片操作中,[num1,num2]里面有两个数字,表示了一段区间
# num1表示开始区间的下标,num2表示结束区间的下标
# 区间为左闭右开 => [num1,num2)

# 2. 使用切片时可以省略边界
a = [1, 2, 3, 4]
# 省略后边界,意思是从开始位置,一直取到整个列表结束
print(a[1:])
# 省略前边界,意思是从列表0号元素开始取,一直取到结束的后边界
print(a[:2])
# 此处切片中的下标也可以写成负数
print(a[:-1])
# 还可以把开始边界和结束边界都省略掉,得到的还是列表自身
print(a[:])

# 切片操作是一个比较高效的操作,进行切片的时候,只是取出了原有列表中的一个部分,并不涉及到"数据的拷贝",假设有一个很大的列表,进行切片,即使切片范围也很大,切片操作仍然很高效

# 3. 带有步长的切片操作
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
# 第三个数字是步长,表示隔几个元素取
print(a[::1])
print(a[::2])
print(a[::3])
print(a[1:-1:2])

# 4.步长的数值还可以是负数,表示从后往前取元素
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
print(a[::-1])
print(a[::-2])

# 5. 当切片中的范围超出有效下标之后,不会出现异常!而是尽可能把符合要求的元素给获取到
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
print(a[1:100])

3.遍历列表

# 列表元素的遍历(把列表的每个元素都依次取出来,并进行某种操作)------不重不漏
# 遍历往往要搭配循环
# 1.使用 for 循环遍历列表
a = [1, 2, 3, 4, 5]
for elem in a:
    print(elem)
# 要求 a 是一个可迭代对象

# 2.使用 for 循环遍历, 通过下标的方式
a = [1, 2, 3, 4, 5]
for i in range(0, len(a)):
    print(a[i])

#1,2两种写法还是有差别的
#如果是想要修改列表中元素的值,那么肯定要采用写法二,一是做不到的

# 代码一
# 没有达到修改列表的目的,只是修改了变量 elem
a = [1, 2, 3, 4, 5]
for elem in a:
    elem = elem + 10
print(a)

# 代码二
# 达到了修改变量的目的
a = [1, 2, 3, 4, 5]
for i in range(0, len(a)):
    a[i] = a[i] + 10
print(a)

# 3.使用while循环,通过下标遍历
a = [1, 2, 3, 4, 5]
i = 0
while i < len(a):
    print(a[i])
    i += 1

4.添加元素

# 1.使用append 往列表末尾新增一个元素
a = [1, 2, 3, 4]
a.append(5)
a.append('hello')
print(a)
# 此处的 append 函数要搭配列表对象a来使用,而不是作为一个单独的函数
# 之前的 len, print, input, type.........都是独立的函数
# 这种要搭配对象(在Python中,对象就可以视为变量)来使用的函数(function),也叫"方法"(method)

# 2.使用 insert 方法,往列表的任意位置来新增元素
# insert(参数1,参数2)  参数1---要插入位置的下标  参数2---要插入的元素
a = [1, 2, 3, 4]
a.insert(1, 'hello')
print(a)
# 当插入下标越界时,会默认插到列表尾部
a.insert(100, 'hello')
print(a)

5.查找元素

# 1.使用 in 来判定某个元素是否在列表中
# in : 存在返回 True , 不存在 Fasle
# not in : 不存在返回 True , 存在返回 False
a = [1, 2, 3, 4]
print(1 in a)
print(1 in a)

# 2.使用 index 方法,来判定当前元素在列表中的位置,存在返回查找元素下标,不存在抛出异常
# 不存在抛出异常,这点和C++/Java是不同的,在C++/Java中,查找不到一般返回-1(因为下标不可能为负数,但是Python中下标有-1,所以直接抛出异常)
a = [1, 2, 3, 4]
print(a.index(2))
# print(a.index(10))

6.删除元素

# 1.使用 pop 删除列表最末尾元素
a = [1, 2, 3, 4]
a.pop()
print(a)

# 2.使用 pop 删除任意位置的元素. pop的参数可以传一个下标过去
a = [1, 2, 3, 4]
a.pop(1)
print(a)

# 3.使用 remove 方法,可以按照值来进行删除
a = ['aa', 'bb', 'cc', 'dd']
a.remove('cc')
print(a)

7.列表拼接

# 使用 + 针对两个列表进行拼接
# 只是针对当前列表内容生成了一个更大的列表,原有列表内容不变
a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
c = a + b
print(c)
c = b + a
print(c)

# 2.使用 extend 拼接
# 把后一个列表内容拼接到前一个列表里面,会修改前一个列表,没有返回值
a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
a.extend(b)
print(a)
print(b)
# c为 None(类似于C里面的 NULL /Java里的 null)
c = a.extend(b)
print(c)

# 3.使用 += 来进行拼接
a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
a += b
print(a)
print(b)

ps:注意区分 extend 和 += 本质区别

元组:

上文已经提到,元组和列表非常相似,所以很多功能只需要把列表中的[ ] 改成 () 即可,最大的区别便是元组不可修改

# 1.创建元组
a = ()
print(type(a))
b = tuple()
print(type(a))

# 2.创建列表的时候,指定初始值
a = (1, 2, 3, 4)
print(a)

# 3.元组中的元素也可以是任意类型的
a = (1, 2, 'hello', True, [])
print(a)

# 4.通过下标访问元素,下标范围 0 - len - 1
a = (1, 2, 3, 4)
print(a[1])
print(a[-1])
# 下标越界抛出异常
# print(a[100])

# 5.切片操作获取元组部分
a = (1, 2, 3, 4)
print(a[1:3])

# 6.for 循环等方式遍历元素
a = (1, 2, 3, 4)
for elem in a:
    print(elem)

# 7.可以使用 in 判定元素是否存在, 使用index 查找元素下标
a = (1, 2, 3, 4)
print(3 in a)
print(a.index(3))

# 8.使用 + 来拼接两个元组
a = (1, 2, 3, 4)
b = (5, 6, 7, 8)
print(a + b)

# 9.元组只支持"读"操作,不支持"修改"操作
a = (1, 2, 3, 4)


# a[0] = 100
# a.pop(0)---元组压根就没有 pop 方法

# 10.当进行多元赋值的时候, 其本质上是按照元组的方式来进行工作的
def get_point():
    x = 10
    y = 20
    return x, y


m, n = get_point()
print(type(get_point()))   # 此处的返回值类型便是元组

既然这样列表既可以读取,也可以修改,那么元组存在的意义是什么呢?

在协同开发中,程序员A实现一些功能,提供给B程序员使用,A写好一些函数,让B去调用,函数肯定要传参,B在传参时会纠结把参数传过去之后,A的函数是否会把参数给修改了呢?,如果使用元组作为参数,就可以避免这样的纠结

元组不能修改=>不可变对象~~

不可变对象,是可以哈希的!

字典:

一种存储 键值对 的结构

重要概念: 键值对

键 --- key

值 --- value

根据 key 能够快速找到 value , 构成映射关系

例如在校学生 的学号 =>人

在Python字典中,可以同时包含很多个键值对,同时要求这些键,不能重复

1.字典创建

# 1.创建字典
a = {}
print(type(a))
b = dict()
print(type(b))

# 2.创建字典的同时设置初始值
a = {'id': 1, 'name': 'zhangsan', }
# 末尾的逗号可有可无
# 一个字典中的key类型不必一样,一个字典中的value类型也不必一样
# 字典对于 key是啥类型有约束,对value是什么类型没有约束
# 更好的字典书写方式:多行书写(更加直观)
a = {
    'id': 1,
    'name': 'zhangsan',
}

2.查找key

# 1.使用 in 来判定某个 key 是否在字典中存在
a = {
    'id': 1,
    'name': 'zhangsan',
}
print('id' in a)
print('classid' in a)

# 注意 in 只是判定 key 是否存在,和value无关
print('zhangsan' in a)  # 依然是False
# not in 判定 key 在字典中不存在

# 2.使用 [] 来根据 key 获取到 value
a = {
    'id': 1,
    'name': 'zhangsan',
    100: 'list'
}

print(a['id'])
print(a['name'])
print(a[100])
print(a['classeid'])   # 报错

ps:对于字典来说,使用 in 或者 [ ] 来获取 value ,都是非常高效的操作!   (字典背后使用了特殊的数据结构---哈希表)

字典被设计出来的初衷,不是为了遍历,而是为了增删查改

字典是 哈希表 ,进行增删查改操作,效率是非常高的!而字典的遍历则效率就要差一些

哈希表这个结构设计的非常巧妙,能够以"常数级"时间复杂度来完成增删改查

无论字典有多少元素,新增,修改,查找,删除操作都是固定时间,不会因为元素多了,操作就慢了

(后面文章讲)

对于列表来说,使用 in 比较低效(需要遍历整个列表),而使用[ ] 比较高效(类似于数组/顺序表取下标)

3.新增/修改/删除操作

# 1.在字典中新增元素,使用 [] 来进行
a = {
    'id': 1,
    'name': 'zhangsan',
}
a['score'] = 90
print(a)

# 2.在字典中,根据 key修改value 也是使用 [ ] 来进行的
a = {
    'id': 1,
    'name': 'zhangsan',
    'score': 90
}
a['score'] = 100

# key 不存在就是新增, Key存在就是修改
# 与变量创建和修改类似~

# 3.使用pop 方法,根据 key 删除键值对
a = {
    'id': 1,
    'name': 'zhangsan',
    'score': 90
}
a.pop('name')
print(a)

# 体会:字典中的各种操作,都是针对 key 来进行的!!!

4.字典遍历

# 使用 for 循环遍历列表
# 法一:
a = {
    'id': 1,
    'name': 'zhangsan',
    'score': 90
}
for key in a:
    print(key, a[key])

# 注意在C++/Java 中,哈希表里面的键值对存储的顺序是无序的
# 但是在Python中是不一样的,Python中做了特殊处理!!!能够保证遍历出来的顺序就是和插入的顺序一致的
# Python中的字典又不是一个单纯的哈希表(按照哈希表的方式组织键值对,又按照队列的方式来控制元素的先进先出)

# keys获取到字典中的所有key
a = {
    'id': 1,
    'name': 'zhangsan',
    'score': 90
}
print(a.keys())  # 返回结果看起来是个列表但不完全是列表,是一个自定义的类型--- dict_keys,可以当成列表来使用

# values获取到字典中的所有value
a = {
    'id': 1,
    'name': 'zhangsan',
    'score': 90
}
print(a.values())

# items 获取到字典中所有的键值对
a = {
    'id': 1,
    'name': 'zhangsan',
    'score': 90
}
print(a.items())  # 返回结果是一个列表一样的结构,里面每个元素又是一个元组,元组里面包含了键和值

# 法二:
for key, value in a.items():
    print(key, value)

5.合法的 key 类型

不是所有的类型都可以作为字典的 key

字典本质上是一个哈希表,哈希表的 key 要求是"可哈希"的,也就是可以计算出一个哈希值

在Python中,专门提供了一个 hash函数,用来计算哈希值

不可变得对象,一般就是可哈希的

可变对象,一般是不可哈希的

# 使用 hash 函数,可以计算出一个变量的哈希值
print(hash(0))
print(hash(3.14))
print(hash('hello'))
print(hash(True))
print(hash((1, 2, 3)))

# 有的类型是不能计算哈希值的
print(hash([1, 2, 3]))  # 报错
print(hash({}))  # 报错

字典,列表,元组Python中非常常用的内置类型~相比于int ,str, float.....他们内部可以再包含其他元素

这些被统称为容器/集合类~

文件

1.文件是什么?

文章开篇便已经介绍了计算机相关知识,计算机包括cpu,存储器,输入输出设备

变量是在内存中的,而文件就是在硬盘当中

------硬盘上存储的数据就是以文件的形式来组织的~~~(此电脑=>C盘/D盘,这里的内容都是硬盘上的内容,也都是文件)     

------文件夹(目录)也是一种特殊的文件叫做目录文件

即使都是文件,文件里面存储数据的内容/格式,差异也是很大的

本篇重点讲解的是文本文件

2.文件路径

文件夹/目录:

文件夹再包含文件夹的情况~~~

此处把一层一层的目录构成的字符串,就称为"文件的路径"

例如为了表示 电脑中qq.exe 这个文件的位置,就可以通过路径的方式来表示

知道了文件路径,就可以知道这个文件在硬盘上的详细位置,也就可以进一步知道这个文件里有啥了,也就可以使用文件了,文件路径可以视为文件在硬盘上的身份标识.每个文件对应的路径都是唯一的

目录名之间,使用 \ 来分割.其实使用 / 也行(Windows系统),而ios系统和linux系统都是采用 /

在代表中表示一个文件路径,用\更多!使用 \  不太方便,\在字符串里有特殊含义,表示"转义字符"

\\在字符串里才表示字符\,\在字符里,是特定含义的转义字符~~~

3.文件操作

①打开文件

# 使用 open 打开一个文件
f = open('d:/Python环境/test.txt', 'r')
print(f)
print(type(f))

 # 当文件不存在时,尝试按照读的方式打开,就会抛出"文件没找到"异常

# 第一个参数表示要打开文件的路径
# 第二个参数表示打开的方式
# 而打开方式有很多种,例如:
# r表示 read, 按照读方式打开
# w 表示 write, 按照写方式打开
# a表示append,把内容写到原有文件内容的后面
# f是file的缩写,意思是这是一个文件对象
# open的返回值是一个文件对象,如何理解?
# 文件的内容是在硬盘上的,此处的文件对象,则是内存上的一个变量~ 后续读写文件操作,则是拿着这个文件对象来进行操作的
# 此处的文件对象相当于一个遥控器
# 计算机中,也把这样的远程操作的"遥控器"成为句柄(handler)

②读文件

这是我在D盘创建的一个文件

# 1.使用 read 来读取文件内容,指定几个字符
f = open('d:/Python环境/test.txt', 'r')
result = f.read(2)
print(result)
f.close()

为什么会报错呢???

中文和英文类似,在计算机中,都是使用"数字"来表示字符的

哪个数字对应哪个汉字?其实在计算机中,可以有多个版本

最主流的版本有两个: GBK/UTF8

在实际开发的时候,就需要保证文件内容的编码方式和代码中操作文件的编码方式相匹配

报错信息表明当前代码是在按照 gbk 来解析,但是可以看到我的文件格式是 utf 8

此处我们使用的办法是 让代码按照 utf 8 来进行处理,相比于 gbk , utf8 是使用更广泛的编码方式~

我们只需要指定open第三个参数(关键字参数)即可

# 1.使用 read 来读取文件内容,指定几个字符
f = open('d:/Python环境/test.txt', 'r', encoding='utf8')
result = f.read(2)
print(result)
f.close()
# 2.更常见的需求是按行来读取
# 最简单的办法,直接 for 循环
f = open('d:/Python环境/test.txt', 'r', encoding='utf8')
for line in f:
    print(f'line = {line}')
f.close()

但是会发现读取结果每两行之间还有一个空行,因为本来读到的文件内容(这一行末尾,就有一个\n),

print 来打印, 又会自动添加一个换行符

可以给print再多设定一个参数,修改print 自动添加换行的行为(print第三个参数默认是换行符)

# 2.更常见的需求是按行来读取
# 最简单的办法,直接 for 循环
f = open('d:/Python环境/test.txt', 'r', encoding='utf8')
for line in f:
    print(f'line = {line}', end='')
f.close()
# 3.使用 readlines 方法直接把整个文件所有内容都读取出来,按照行组织到一个列表里
f = open('d:/Python环境/test.txt', 'r', encoding='utf8')
lines = f.readlines()
print(lines)
f.close()

③写文件

# # 使用 write 来实现写文件的操作
# f = open('d:/Python环境/test.txt', 'w')
# f.write('hello')
# f.close()
#
# # 写文件时,需要用 w 的方式打开,如果使用 r 的方式打开,则会抛出异常
# f = open('d:/Python环境/test.txt', 'r')
# f.write('hello')
# f.close()

# 写方式有两种情况,直接写方式打开,追加写方式打开~~

# 直接写的方式打开,会清空掉文件所有的内容化!!
# f = open('d:/Python环境/test.txt', 'w')
# f.close()

# 如果使用 a 的方式打开,则不会清空, 写的内容会追加到原有文件的末尾
f = open('d:/Python环境/test.txt', 'w')
f.write('1111\n')
f.close()

f = open('d:/Python环境/test.txt', 'a')
f.write('2222')
f.close()

# 如果文件对象已经被关闭,那么意味着系统中和该文件相关的内存资源都已经释放了,强行去写,就会抛出异常
f = open('d:/Python环境/test.txt', 'w')
f.close()
f.write('hello')

④关闭文件

f = open('d:/Python环境/test.txt', 'r')
print(f)
print(type(f))
f.close()
# 文件在打开完之后,使用完之后,也就一定要关闭!!!
# 打开文件,其实都是在申请一定的系统资源~
# 不再使用文件的时候,资源就应该及时释放,否则就有可能造成文件资源泄漏,导致其他部分的代码无法顺序打开文件了~
# 正是因为一个系统的资源是有限的,因此一个程序能打开的文件个数也是有上限的

 ps:在系统中可以通过一些设置项,来配置能打开文件的最大数目的 .....但是无论配置多少,都不是无穷无尽的, 就需要记得及时关闭,释放资源~

文件资源泄漏其实是一个挺重要的问题,不会第一时间暴露出来,而是在角落里,突然偷袭一下~

---------拓展:

上述代码中刚好打开了8189个文件,这个数字有什么特殊的吗?

8189 + 3 = 8192 = 2^13

计算机中是使用二进制来表示数据的, 因此计算机里的很多数据都是按照2的多少次方这样的数据来表示的~

在程序员眼里,1000并不是一个很整齐的数字,1024(2^13)才是一个比较整齐的数字!!

3是哪来的???

一个程序在启动的时候,都会默认打开三个特殊文件(特殊在这三个文件不是对应到磁盘,而是对应到键盘和显示器)

1.标准输入---键盘--------input

2.标准输出---显示器-----print

3.标准错误---显示器

上述代码中一个重要的细节:

上述有一句代码: flist.append(f) 这句代码是干嘛的?

如果屏蔽掉这句代码结果又会怎样呢?

# 打开文件个数的上限
flist = []
count = 0
while True:
    f = open('d:/Python环境/test.txt', 'r')
    # flist.append(f)
    count += 1
    print(f'打开文件的个数: {count}')

这个时候就会发现不存在"打开文件上限"这一现象了,这就涉及到一个重要的细节~~~

Python中有一个重要的机制---垃圾回收机制(GC),自动的把不使用的变量给进行释放

加上 flist.append(f) 这句代码,Python就会认为每次循环创建的 f 变量是有用的,系统就不会自动回收,而去掉这句代码后,系统就会认为每次循环完毕之后f 没有被使用于是就认为 f 是垃圾,于是系统进行了自动回收,就相当于进行了 我们手动 f.close()操作

ps:虽然Python给我们留了一个后手,让我们在一定程度上能够避免上述问题,但是也不能完全依赖自动释放机制~~因为自动释放不一定及时~~

机制 ------- 上下文管理器

解决文件容易忘记关闭的问题

# 有些情况还是非常容易遗漏 close 的,防不胜防
def func():
    f = open('d:/Python环境/test.txt', 'r', encoding='utf8')
    # 中间来写其他的操作文件的逻辑
    # 万一中间的代码里,有条件判定,函数返回,抛出异常~~~
    if cond:
        # 另外一些代码
        return
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    # 另外一些代码 
    f.close()

而使用上下文管理器就可以解决这个问题

当 with 对应的代码块执行结束,就会自动执行对应的 f 的close

def func():
    with open('d:/Python环境/test.txt', 'r', encoding='utf8') as f:
        # 进行文件这里的处理逻辑
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码
        if cond:
            return
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码
        if cond:
            return
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码
        #假设这里有很多代码

 这种机制在很多编程语言都有

例如 C++中的智能指针, Java中的 try with Resources, Golang 中的 defer

Python通过模块来体现"库"

1.降低程序员学习的成本

2.提高程序到开发效率

一个编程语言能否流行起来, 一方面取决于语法是否简单易于学习, 另一方面要看生态是否完备(是否有丰富的库)

库可以分为两个大类:

1.标准库: Python自带的库

2.第三方库: 其他大佬做出来的

第三方库是非常非常庞大的,数量和种类 >> 标准库

代码案例

------------------------------标准计算器:---------------------------------------------------------------------------------

计算两个时间点之间的时间间隔

import datetime

# 先构造 datetime 变量
# 注意第一个 datetime 是模块名, 第二个 datetime 是类型名
date1 = datetime.datetime(year=2012, month=2, day=14)
date2 = datetime.datetime(year=2016, month=2, day=3)
print(date2 - date1)

# 改进写法
from datetime import datetime

date1 = datetime(year=2012, month=2, day=14)
date2 = datetime(year=2016, month=2, day=3)
print(date2 - date1)

# 另外写法
import datetime as dt

date1 = dt.datetime(year=2012, month=2, day=14)
date2 = dt.datetime(year=2016, month=2, day=3)
print(date2 - date1)

leetcode 刷题

-------------------------------------------------字符串相关题目---------------------------------------------------

------------------------------------------翻转句子之间的单词顺序----------------------------------------------

题目:

思路:

1.针对字符串 使用 空格分隔 字符串 split 方法, 可以指定分隔符,把字符串分成多个部分, 放到一个list 里面

2.针对刚才的切分结果列表,用 reverse 进行逆序~

3.再把逆序后的列表,用 join 组合起来

def reverseWords(s: str):
    tokens = s.split(' ')
    tokens.reverse()
    return ' '.join(tokens)


print(reverseWords("I am a student."))

ps:上述的 s: str 上文已经解释过了,是用来声明变量类型的,这样的好处便是解释器可以很方便的进行提示我们 split / reverse 等方法

------------------------------------------------旋转字符串···························································

题目:

旋转规则: abcde 旋转一次  ------>   bcdea -------> cdeab -------> deabc --------> eabcd

思路: 无论如何旋转,都可以发现 新的字符串 goal 是 abcdeabcde(原本两个字符串合并 ------  s + s)的子串

def rotateString(s, goal):
    if len(s) != len(goal):
        return False
    return goal in (s + s)


print(rotateString("abcde", "cdeab"))
print(rotateString("abcde", "cdeba"))

先判断长度,不相等则直接排除,然后看 goal 是否包含在 s + s 这样的字符串中
 

-----------------------------------------------------   统计字符串前缀---------------------------------------------------

 思路: 1.遍历 words 列表   2.使用 str 中的 startswith 方法判断 words 中的元素是不是 str 的前缀

3. 使用 计数器变量 count 统计个数

def countPrefixes(words: list, s: str):
    count = 0
    for word in words:
        if s.startswith(word):
            count += 1
    return count


count1 = countPrefixes(['a', 'b', 'c', 'ab', 'bc', 'abc'], 'abc')
count2 = countPrefixes(['a', 'a'], 'aa')
print(count1)
print(count2)

----------------------------------------用Python实现文件搜索工具-----------------------------------------------------

实际问题:

我们电脑中常常有很多目录,很多文件~~,想要找到某个文件,并不太容易

像 everything 这样的软件 就是一款成熟 的文件搜索工具

而现在我们想要通过 Python 代码 来实现类似 everything 的查找功能 (递归查找,遇到子目录.就进入目录中进行查找)

标准库: os.walk  只需要简单的循环,就能完成递归遍历的过程,每次调用都能自动地去针对子目录进行递归的操作,只要使用循环,就可以把所有的路径获取出来

# 输入要查找的路径, 输入要搜索的文件名(一部分)
# 自动地在指定的路径中进行查找
import os
inputPath = input("请输入要搜索的路径:")
pattern = input("请输入要搜索的关键词:")
# 进行目录文件的遍历
# dirpath: 遍历到当前位置对应的路径是啥
# dirname: 当前目录下有哪些目录
# filenames: 当前目录下都有哪些文件名, 是一个列表,可以包含多个文件
for dirpath, dirnames, filenames in os.walk(inputPath):
    print('--------------------')
    print(f'dirpath = {dirpath}')
    print('dirnames:')
    for name in dirnames:
        print(name)
    print('filenames:')
    for name in filenames:
        print(name)

上述代码简单的演示了os.walk的用法

import os
inputPath = input("请输入要搜索的路径:")
pattern = input("请输入要搜索的关键词:")
# 进行目录文件的遍历
# dirpath: 遍历到当前位置对应的路径是啥
# dirname: 当前目录下有哪些目录
# filenames: 当前目录下都有哪些文件名, 是一个列表,可以包含多个文件
for dirpath, _, filenames in os.walk(inputPath):
    for f in filenames:
        if pattern in f:
            print(f'{dirpath}/{f}')

这样便实现了 类似 everything 的查找功能

Python的第三方库:

手机上有各种来自不同厂商的app,而应用商店把这些app管理起来,我们想使用哪个app直接去下载即可

而Python的第三方库也是如此!

Python搞了一个官方网站 pypi(PyPI · The Python Package Index), 把各种第三方库收集起来了~~

又提供了一个 pip 工具, 使用pip就直接能从 pypi上下载想要的第三方库了

pip 可以视为是 Python 世界中的应用商店,而安装Python的时候,就已经自动的把pip安装好了,直接就能使用

pip是一个命令行,有两种方式打开pip

第一种方法就是在Pycharm的右下角,点击Terminal 选项 即可

 第二种方式就是  开始键(windows键) + r, 输入cmd即可

代码案例:

生成二维码

二维码的本质是字符串,我们可以把任意字符串制成一个二维码图片~~

生活中使用的二维码,更多的是一个URL(网址)

第三方库 qrcode 就是一个用来生成二维码的库

打开pip后, 输入pip install qrcode[pil] 便能安装 qrcode 库

import qrcode
img = qrcode.make()
img.save('qrcode.png')

 

Python的基础知识就到此结束了,欢迎大家交流指正
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值