Python数据结构与算法(1(2)

var

False

赋值语句 var = 12.345 用于创建变量 var,并且令 var 保存指向数据对象 12.345 的引用。Python 会先计算赋值运算符右边的表达式,然后将指向结果数据对象的引用赋给左边的变量名。如果数据的类型发生改变,例如将布尔值 False 赋值给 var,则变量 var 的类型也会变成布尔类型。这体现了 Python 的动态特性,即赋值语句可以改变变量的引用,同样的变量可以指向不同类型的数据。

变量与赋值

3. 数据


由于 Python 是面向对象编程的编程语言,因此,在 Python编程语言中,数据同样是对象,而对象是类的实例。类是对数据的构成以及数据所能进行操作的描述,这与抽象数据类型十分类似。

3.1 原子数据类型

Python 提供 intfloat 类来实现整数类型和浮点数类型,并包含标准数学运算符(可以通过括号改变运算优先级),如下所示:

| 运算名 | 运算符 | 解释 |

| — | — | — |

| 加 | + | 加法运算符 |

| 减 | - | 减法运算符 |

| 乘 | * | 乘法运算符 |

| 除 | / | 除法运算符,结果为浮点数 |

| 幂 | ** | 幂运算符 |

| 求余 | % | 求余(取模)运算符 |

| 整除 | // | 整除运算符,与 / 不同,// 会截去小数部分,只返回商的整数部分 |

下面给出整数类型、浮点数类型及运算符的使用示例:

10 - 5 * 5

-15

(10 - 5) * 5

25

12.5 * 3.3

41.25

12 / 2

6.0

13 / 2

6.5

13 // 2

6

3 ** 3

27

13 % 2

1

Python 通过 bool 类实现布尔数据类型,其可能的状态值包括 TrueFalse,布尔运算符有 andor 以及 not,同时布尔对象也可以用于相等 (==)、大于 (>) 等比较运算符的计算结果:

| 运算名 | 运算符 | 解释 |

| — | — | — |

| 大于 | > | 大于运算符 |

| 大于等于 | >= | 大于等于运算符 |

| 小于 | < | 小于运算符 |

| 小于等于 | <= | 小于等于运算符 |

| 相等 | == | 相等运算符,判断两个操作数是否相等,如果相等返回 True |

| 不相等 | != | 不相等运算符,判断两个操作数是否不相等,如果不相等返回 True |

| 逻辑与 | and | 两个操作数都为 True 时返回 True |

| 逻辑或 | or | 任意一个操作数为 True 时返回 True |

| 逻辑非 | not | 对操作数取反,False 变为 True,True 变为 False |

下面给出布尔类型及运算符的使用示例:

True

True

False or True

True

not (True and False)

True

11 != 111

True

1024 <= 1024

True

(1024 >=1000) and (1024 <= 1000)

False

3.2 结构数据类型

除了上述原子数据类型外,Python 还包含许多原生的结构数据类型:1) 有序结构数据类型——列表、字符串以及元;2) 无序结构数据类型——集和与字典。

需要注意的是这里的有序是指在插入的时候,保持插入的顺序性:

保持插入的顺序性

list([1,2,3,7,5])

[1, 2, 3, 7, 5]

未保持插入的顺序性

set([1,2,3,7,5])

{1, 2, 3, 5, 7}

3.2.1 通用的序列运算

有序数据结构也可以称为序列。序列在处理系列值时非常有用,例如我们有一个购物清单,如果使用列表来表示(所有元素都放在方括号内,元素间用逗号分隔),形式如下:

shopping = [‘cabbage’, ‘apple’, ‘beef’]

序列可以包含其他序列,例如上示列表中,每个元素就由字符串序列组成,同时列表中也可以包含列表:

shopping = [[‘cabbage’, 2], [‘apple’, 5], [‘beef’, ‘50’]]

序列支持一系列 Python 运算,如下所示:

| 运算名 | 运算符 | 解释 |

| — | — | — |

| 索引 | [] | 获取序列中的某一元素 |

| 切片 | [:] | 获取序列中的指定部分元素 |

| 连接 | + | 将序列进行连接 |

| 重复 | * | 重复序列N次 |

| 成员 | in | 查询序列中是否含有某一元素 |

| 成员 | not in | 查询序列中是否不包含某一元素 |

| 长度 | len | 查询序列的元素个数 |

🔍 索引

序列中的所有的每个元素都有其索引 (indexing),索引是从 0 开始递增的,利用索引就可以访问序列中的每个元素了:

shopping = [‘cabbage’, ‘apple’, ‘beef’]

shopping[0]

‘cabbage’

Python 中也可以使用负数索引,用于从右向左进行编号,即 -1 是序列最后一个元素的位置,这在我们仅需取序列末尾元素时非常有用:

shopping[-2]

‘apple’

序列也可以直接进行索引操作,而无需首先将其赋值给变量:

[‘cabbage’, ‘apple’, ‘beef’][-1]

‘beef’

同样如果函数的返回结果为一个序列,我们也可以直接对其进行索引操作 (关于 input 函数将在 4.1 节详细描述):

example = input('Please enter your name: ')[1]

Please enter your name: alice

example

‘l’

🔍 切片

索引的作用是用来访问单个元素,而切片 (slicing) 则可以用于访问序列中指定范围内的元素,切片使用两个冒号分隔的两个索引:

number = [1, 2, 3, 4, 5]

number[1:4]

[2, 3, 4]

number[1:-1]

[2, 3, 4]

从以上示例可以看出,第一个索引指向的元素包含在切片内,第二个索引指向的元素不在切片内。

使用切片语法时,如果省略第二个索引,则切片会取到序列末尾;如果省略第一个索引,则切片会从序列开头开始取;如果两个索引都省略,则会取整个序列:

url = ‘https://www.python.org’

sever = url[12:-4]

sever

‘python’

domain = url[12:]

domain

‘python.org’

protocol = url[:5]

protocol

‘https’

copy_url = url[:]

copy_url

‘https://www.python.org’

除此之外,切片运算还支持使用步长,即从起点和终点之间每隔若个元素提取一个元素,默认情况下,步长为 1,若步长为负数,即从终点到起点提取元素:

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

numbers[0:10:1]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

numbers[0:10:2]

[0, 2, 4, 6, 8]

numbers[0:6:3]

[0, 3]

numbers[::3]

[0, 3, 6, 9]

numbers[10::-1]

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

numbers[10::-2]

[9, 7, 5, 3, 1]

🔍 连接

可使用加法运算符将多个序列连接为一个,但需要注意的是,不同类型的序列不能进行连接:

[‘a’, ‘b’, ‘c’] + [‘d’, ‘e’] + [‘f’]

[‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’]

'Hello ’ + ‘world!’

‘Hello world!’

‘Hello’ + [‘a’, ‘b’, ‘c’]

Traceback (most recent call last):

File “”, line 1, in

TypeError: can only concatenate str (not “list”) to str

🔍 重复

可使用乘法运算符将一个序列重复多次来创建一个新序列:

‘love you!’ * 3

‘love you!love you!love you!’

[1,2] * 5

[1, 2, 1, 2, 1, 2, 1, 2, 1, 2]

[None] * 5

[None, None, None, None, None]

🔍 成员

使用运算符 innot in 可以检查特定值是否包含或不包含在序列中,并返回指示是否满足的布尔值:满足时返回 True, 不满足时返回 False

names = [‘root’, ‘xiaohui’, ‘xiaohuihui’]

‘root’ in names

True

‘hui’ in names

False

‘hui’ not in names

True

🔍 长度

内置函数len返回序列包含的元素个数:

names = [‘root’, ‘xiaohui’, ‘xiaohuihui’]

len(names)

3

3.2.2 列表

除了可以应用通用的序列操作外,列表有很多特有的方法:

| 方法名 | 用法 | 解释 |

| — | — | — |

| index | listA.index(item) | 返回 item 在列表中首次出现的下标 |

| count | listA.count(item) | 返回 item 在列表中出现的次数 |

| append | listA.append(item) | 在列表末尾添加新元素 item |

| extend | listA.extend(listB) | 将列表 listB 附加到列表 listA 末尾 |

| insert | listA.insert(i, item) | 在列表的第 i 个位置插入元素 item |

| pop | listA.pop(i) | 删除并返回列表中第 i 个位置的元素,如果不指定参数 i,则删除并返回列表中最后一个元素 |

| remove | listA.remove(item) | 移除在列表中首次出现的 item |

| sort | listA.sort() | 将列表元素排序 |

| reverse | listA.reverse() | 将列表元素按相反的顺序排列 |

| del | del listA[i] | 删除列表中第 i 个位置的元素 |

| clear | listA.clear() | 清空列表 listA 的内容 |

| copy | listA.copy() | 复制列表 listA |

1 基本列表操作

接下来将介绍用于创建、修改列表的方法。

🔍 list 函数

使用函数 list 可以将创建空列表或将任何序列转换为列表:

empty_list = list()

[]

string_test = list(‘Python’)

string_test

[‘P’, ‘y’, ‘t’, ‘h’, ‘o’, ‘n’]

range 是一个常见的 Python 函数,它常与列表一起讨论。使用 range 可以生成值序列的范围对象,然后利用 list 函数,能够以列表形式看到范围对象的值,同时也和切片语法类似,其支持使用步长参数:

list(range(10))

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

list(range(1, 10))

[1, 2, 3, 4, 5, 6, 7, 8, 9]

list(range(1, 10, 2))

[1, 3, 5, 7, 9]

🔍 修改列表元素

修改列表只需结合索引使用普通赋值语句即可,使用索引表示法可以修改特定位置的元素:

numbers[0] = 11

numbers

[11, 1, 2, 3, 4, 5, 6, 7, 8, 9]

使用切片语法可以同时给多个元素赋值,通过使用切片赋值,可将切片替换为长度与其不同的序列,或者插入、删除元素:

fruits = [‘apple’, ‘orange’, ‘banana’, ‘pear’, ‘strawberry’]

fruits[2:] = [‘lemon’, ‘watermelon’]

fruits

[‘apple’, ‘orange’, ‘lemon’, ‘watermelon’]

fruits[1:1] = [‘grape’]

fruits

[‘apple’, ‘grape’, ‘orange’, ‘lemon’, ‘watermelon’]

fruits[1:3] = []

fruits

[‘apple’, ‘lemon’, ‘watermelon’]

🔍 删除元素

从列表中删除元素可以使用 del 语句:

fruits = [‘apple’, ‘orange’, ‘banana’, ‘pear’, ‘strawberry’]

del fruits[0]

fruits

[‘orange’, ‘banana’, ‘pear’, ‘strawberry’]

del fruits[1:3]

fruits

[‘orange’, ‘strawberry’]

2 列表方法

方法是与对象紧密联系的函数,方法调用与函数类似,需要在方法名前加上了对象和句点:

object.method(arg)

🔍 index 方法

index 方法在列表中查找指定值第一次出现的索引:

fruits = [‘apple’, ‘orange’, ‘banana’, ‘pear’, ‘strawberry’]

fruits.index(‘orange’)

1

fruits.index(‘lemon’)

Traceback (most recent call last):

File “”, line 1, in

ValueError: ‘lemon’ is not in list

查找单词“orange”时,返回其索引 4,但是当搜索列表中不存在的单词“lemon”时,会引发异常。

🔍 count 方法

count 方法用于统计指定元素在列表中的数量:

fruits = [‘apple’, ‘orange’, ‘banana’, ‘apple’, ‘orange’, [‘apple’]]

fruits.count(‘apple’)

2

fruits.count([‘apple’])

1

🔍 append 方法

append 方法用于将一个对象添加到列表末尾:

fruits = [‘apple’, ‘orange’, ‘banana’, ‘pear’, ‘strawberry’]

fruits.append(‘lemon’)

fruits

[‘apple’, ‘orange’, ‘banana’, ‘pear’, ‘strawberry’, ‘lemon’]

需要注意的是,与其他修改列表的方式类似,append 方法也是原地操作的,它不会返回修改后的新列表,而是直接在旧列表上进行修改。

🔍 extend 元素

extend 方法可以在一个列表末尾添加另一个列表,可使用一个列表来扩展原列表:

fruits_1 = [‘apple’, ‘orange’]

fruits_2 = [‘banana’, ‘pear’]

fruits_1.extend(fruits_2)

fruits_1

[‘apple’, ‘orange’, ‘banana’, ‘pear’]

与拼接运算符 + 不同的是,extend 方法是原地执行的,而 + 会返回得到的新列表,并非原地执行:

fruits_1 = [‘apple’, ‘orange’]

fruits_2 = [‘banana’, ‘pear’]

fruits = fruits_1 + fruits_2

fruits

[‘apple’, ‘orange’, ‘banana’, ‘pear’]

fruits_1

[‘apple’, ‘orange’]

🔍 insert 方法

insert 方法用于在列表的指定位置插入一个新元素:

fruits = [‘apple’, ‘orange’, ‘banana’, ‘pear’, ‘strawberry’]

fruits.insert(2, ‘lemon’)

fruits

[‘apple’, ‘orange’, ‘lemon’, ‘banana’, ‘pear’, ‘strawberry’]

🔍 pop 方法

pop 方法用于在列表中删除一个指定位置(默认为最后一个)的元素,并返回这一元素:

fruits = [‘apple’, ‘orange’, ‘banana’, ‘pear’, ‘strawberry’]

fruits.pop()

‘strawberry’

fruits

[‘apple’, ‘orange’, ‘banana’, ‘pear’]

fruits.pop(1)

‘orange’

fruits

[‘apple’, ‘banana’, ‘pear’]

🔍 remove 方法

remove 方法用于移除在列表中首次出现的指定元素,但列表中之后出现的同样元素,并不会被删除:

fruits = [‘apple’, ‘orange’, ‘banana’, ‘apple’, ‘strawberry’, ‘apple’]

fruits.remove(‘apple’)

fruits

[‘orange’, ‘banana’, ‘apple’, ‘strawberry’, ‘apple’]

🔍 sort 方法

sort 方法用于对列表原地排序,原地排序意味着对原来的列表按顺序排列,而不是返回排序后列表的副本:

x = [1, 3, 4, 9, 8, 2]

x.sort()

x

[1, 2, 3, 4, 8, 9]

由于 sort 修改原列表且不返回任何值,最终的结果列表是经过排序的。如果要获取排序后的列表的副本,而不修改原列表,需使用函数 sorted

x = [1, 3, 4, 9, 8, 2]

y = sorted(x)

y

[1, 2, 3, 4, 8, 9]

x

[1, 3, 4, 9, 8, 2]

sorted 方法同样可以用于其他序列,但返回值总是一个列表:

sorted(‘Hello world!’)

[’ ', ‘!’, ‘H’, ‘d’, ‘e’, ‘l’, ‘l’, ‘l’, ‘o’, ‘o’, ‘r’, ‘w’]

🔍 reverse 方法

reverse 方法按相反的顺序排列列表中的元素:

x.reverse()

x

[2, 8, 9, 4, 3, 1]

这类似于:

x = [1, 3, 4, 9, 8, 2]

x = x[::-1]

x

[2, 8, 9, 4, 3, 1]

类似的,如果要获取反向排列的列表副本,而不修改原列表,需要使用 reversed 函数:

x = [1, 3, 4, 9, 8, 2]

y = reversed(x)

x

[1, 3, 4, 9, 8, 2]

list(y)

[2, 8, 9, 4, 3, 1]

🔍 clear 方法

clear 方法就地清空列表的内容:

x = [1, 3, 4, 9, 8, 2]

x.clear()

x

[]

🔍 copy 方法

我们已经知道 Python 是基于值的管理方式,因此常规复制只是将另一个名称关联到列表,它们指向的是同一个列表,因此修改其中一个列表,另一个也会改变:

fruits = [‘apple’, ‘orange’, ‘banana’, ‘strawberry’]

fruits_2 = fruits

fruits_2[1] = ‘lemon’

fruits

[‘apple’, ‘lemon’, ‘banana’, ‘strawberry’]

copy 方法用于复制列表,区别在于其使两个变量指向不同的列表,将列表 listB 关联到 listA 的副本:

listA = [‘apple’, ‘orange’, ‘banana’, ‘strawberry’]

listB = listA.copy()

listB[1] = ‘lemon’

listA

[‘apple’, ‘orange’, ‘banana’, ‘strawberry’]

3.2.3 字符串

Python 没有专门用于表示字符的类型,因此一个字符就是只包含一个元素的字符串。前面介绍了列表的方法,而字符串所拥有的方法要更多,其很多方法都是从模块 string 中“继承”而来的。这里并不会介绍所有字符串的方法,只会介绍一些对于之后数据结构和算法最有用的方法。

| 方法名 | 用法 | 解释 |

| — | — | — |

| lower | stringA.lower() | 将字符串中所有字母转换为大写 |

| upper | stringA.upper() | 将字符串中所有字母转换为小写 |

| count | stringA.count(item) | 返回字符串中 item 出现的次数 |

| center | stringA.center(width, fillchar) | 返回长度为 width 的字符串,原字符串居中,fillchar 为填充的字符,fillchar默认值为空格 |

| ljust | stringA.ljust(width, fillchar) | 返回长度为 width 的字符串,原字符串靠左,fillchar 为填充的字符,fillchar默认值为空格 |

| rjust | stringA.rjust(width, fillchar) | 返回长度为 width 的字符串,原字符串靠右,fillchar 为填充的字符,fillchar默认值为空格 |

| find | stringA.find(item) | 返回 item 第一次在字符串中的下标 |

| startswith | stringA.startswith(string) | 检查字符串是否以 string 开始,如果是,返回 True,否则返回 False. |

| endswith | stringA.endswith | 检查字符串是否以 string 结束,如果是,返回 True,否则返回 False. |

| replace | stringA.replace(old, new) | 将指定子串 old 都替换为另一个字符串 new,并返回替换后的结果 |

| split | stringA.split(char) | 以 str 为分隔符分割字符串 |

| join | string.join(listA) | 返回合并 listA 中元素得到的字符串,以 string 作为合并的分割符 |

🔍 lower 和 upper 方法

lower 方法返回字符串的小写版本,而 upper 方法返回字符串的大写版本:

string_1 = ‘Hello World!’

string_1.lower()

‘hello world!’

string_1.upper()

‘HELLO WORLD!’

🔍 count 方法

count 方法返回字符串中指定子串出现的次数:

string_2 = ‘data structure and algorithms’

string_2.count(‘a’)

4

string_2.count(‘th’)

1

🔍 center、ljust 和 rjust 方法

centerljustrjust 方法返回一个字符串,原字符串居中 (center) /居左 (ljust) /居右 (rjust),使用指定字符填充新字符串,使其长度为指定的 width

string_3 = ‘Hello world!’

string_3.center(16, ‘*’)

Hello world!

string_3.ljust(16, ‘*’)

‘Hello world!****’

string_3.rjust(16, ‘-’)

‘----Hello world!’

🔍 find 方法

find 方法在字符串中查找指定子串,如果找到,就返回第一个找到的子串的第一个字符的索引,否则返回 -1:

string_1 = ‘Explicit is better than implicit. Simple is better than complex.’

string_1.find(‘is’)

9

find 方法还支持使用可选参数指定查找的起点和终点,第二个参数指定搜索起点,第三个参数指定搜索终点:

string_1 = ‘Explicit is better than implicit. Simple is better than complex.’

string_1.find(‘is’, 10)

41

string_1.find(‘is’, 10, 40)

-1

🔍 replace 方法

replace 方法将指定子串都替换为另一个字符串,并返回替换后的结果:

string_1 = ‘Hello World!’

string_1.replace(‘World’, ‘Python’)

‘Hello Python!’

🔍 startswith 和 endswith 方法

startswith 方法检查字符串是否是以指定字符串开头,endswith 方法检查字符串是否是以指定字符串结尾,是则返回 True,否则返回 False,同时可以通过可选参数在指定范围内检查:

zen_of_python = ‘Beautiful is better than ugly. Explicit is better than implicit.’

zen_of_python.startswith(‘Beautiful’)

True

zen_of_python.startswith(‘Beautiful’, 1)

False

zen_of_python.endswith(‘ugly’, 0, 31)

False

zen_of_python.endswith(‘ugly’, 0, 29)

True

最后

🍅 硬核资料:关注即可领取PPT模板、简历模板、行业经典书籍PDF。
🍅 技术互助:技术群大佬指点迷津,你的问题可能不是问题,求资源在群里喊一声。
🍅 面试题库:由技术群里的小伙伴们共同投稿,热乎的大厂面试真题,持续更新中。
🍅 知识体系:含编程语言、算法、大数据生态圈组件(Mysql、Hive、Spark、Flink)、数据仓库、Python、前端等等。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 10
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值