【python学习笔记】task04 列表、元组和字符串

【python学习笔记】task04 列表、元组和字符串

  • 数据类型
    • 1.简单数据类型
    • 2.容器类型数据
  • 列表
    • 1.列表的定义
    • 2.列表的创建
    • 3.列表相关的操作符
    • 4.列表内置函数
    • 5.获取列表中的元素
    • 相关资料
    • 练习题
  • 元组
    • 1.创建和访问一个元组
    • 2.更新和删除一个元组
    • 3.元组相关的操作符
    • 4.元组内置函数
    • 5.解压元组
    • 练习题
  • 字符串
    • 1.字符串的定义
    • 2.字符串的切片与拼接
    • 3.字符串内置函数
    • 4.字符串格式化
    • 相关资料
    • 练习题

数据类型

1.简单数据类型

数据类型 关键词
整型
浮点型
布尔型

相关内容见【python学习笔记】task01 变量、运算符、数据类型及位运算

2.容器类型数据

数据类型 关键词 特点
列表 是一种有序和可更改的集合,允许重复的成员
元组 是一种有序且不可更改的集合。允许重复的成员
字典 是一个无序和无索引的集合,没有重复的成员
集合 是一个无序,可变和有索引的集合。没有重复的成员
字符串 由单引号或双引号括起

列表

1.列表的定义

列表是有序集合,没有固定大小,能够保存任意数量任意类型的 Python 对象的位置,或索引,第一个索引是0,第二个索引是1,依此类推。
【基本格式】

[元素1, 元素2, ..., 元素n]

2.列表的创建

(1)创建一个普通列表

x=[元素1, 元素2, ..., 元素n]

【例1】使用基本语法[]创建一个普通列表,并查看其类型

x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
print(x,type(x))

结果为

['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'] <class 'list'>

(2)使用range()创建列表

x=list(range([start,] stop[, step=1]))

【例2】使用range创建列表

x=list(range(10))
print(x,type(x))
print('=====================')

x = list(range(10, 1, -2))
print(x, type(x))

结果为

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] <class 'list'>
=====================
[10, 8, 6, 4, 2] <class 'list'>

(3)使用推导式创建列表
使用列表推导式可以非常方便的创建列表,在开发中经常使用。
【例3】下面展示了几种使用形式

代码 结果
x = [0] * 5 [0, 0, 0, 0, 0]
x = [0 for i in range(5)] print(x, type(x))
x = [i for i in range(10)] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
x = [i for i in range(10, 1, -2)] [10, 8, 6, 4, 2]
x=[i ** 2 for i in range(1, 10)] [1, 4, 9, 16, 25, 36, 49, 64, 81]

(4)创建m*n的二维数组
【例4】下面展示了几种定义方法及其结果

代码 结果
x = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [0, 0, 0]] [[1, 2, 3], [4, 5, 6], [7, 8, 9], [0, 0, 0]]
x = [0 for i in range(5)] print(x, type(x))
x = [[0 for col in range(3)] for row in range(4)] [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
x = [[0] * 3 for row in range(4)] [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

①如果想更改列表中的某个元素的值使用x[m][n]=想更改的数如x[0][0]=1
②如果想按列输出使用for i in x,如:

x = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [0, 0, 0]]
for i in x:
    print(i, type(i))

结果为

[1, 2, 3] <class 'list'>
[4, 5, 6] <class 'list'>
[7, 8, 9] <class 'list'>
[0, 0, 0] <class 'list'>

③x = [a] * 5操作中,只是创建5个指向list的引用,所以一旦a改变,x中5个a也会随之改,例如

x=[[0]*3]*4
print(x)
x[0][0]=1
print(x)

结果为

[[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]]

可以看出没一行的结果都改变了
(5)创建一个混合列表

由于list的元素可以是任何对象,所以可以创建混合列表

mix=[1,'lsgo',3.14,[1,2,3]]
print(x,type(x))

(6)创建空列表
列表名= []

3.列表相关的操作符

【python学习笔记】task04 列表、元组和字符串_第1张图片
(1)「等号 ==」,只有成员、成员位置都相同时才返回True。
(2)列表拼接有两种方式,用「加号 +」和「乘号 *」,前者首尾拼接,后者复制拼接。
(3)使用append, extend, insert可对列表增加元素,它们没有返回值,是直接修改了原数据对象。 而将两个list相加,需要创建新的 list 对象,从而需要消耗额外的内存,特别是当 list 较大时,尽量不要使用 “+” 来添加list

list1 = [123, 456]
list2 = [456, 123]
list3 = [123, 456]

print(list1 == list2)  # False
print(list1 == list3)  # True

list4 = list1 + list2  # extend()
print(list4)  # [123, 456, 456, 123]

list5 = list3 * 3
print(list5)  # [123, 456, 123, 456, 123, 456]

list3 *= 3
print(list3)  # [123, 456, 123, 456, 123, 456]

print(123 in list3)  # True
print(456 not in list3)  # False

4.列表内置函数

详细用法点击对应方法查看

方法 描述
append() 在列表的末尾添加一个元素
clear() 删除列表中的所有元素
copy() 返回列表的副本
count() 返回具有指定值的元素数量
extend() 将列表元素(或任何可迭代的元素添加到当前列表的末尾)
index() 返回具有制定值的第一个元素的索引
insert() 在指定位置添加元素
pop() 删除制定位置的元素
remove() 删除具有指定值的项目
reverse() 颠倒列表的顺序
sort() 对列表进行排序
print('==使用append()添加元素,此元素如果是一个 list,那么这个 list 将作为一个整体进行追加==')
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
x.append(['Thursday', 'Sunday'])
print(x,'\n') 

print('==使用extend()添加元素,在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)===')
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
x.extend(['Thursday', 'Sunday'])
print(x,'\n') 

print('==list.insert(index, obj) 在编号 index 位置插入 obj==')
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
x.insert(2, 'Sunday')
print(x,'\n') 

print('==使用list.remove(obj) 移除列表中某个值的第一个匹配项==')
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
x.remove('Monday')
print(x,'\n') 

print('==使用list.pop([index=-1]) 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值==')
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
y = x.pop()
print(y,'\n')

print('==使用del var1[, var2 ……] 删除单个或多个对象,如果你要从列表中删除一个元素,且不再以任何方式使用它,就使用del语句;如果你要在删除元素后还能继续使用它,就使用方法pop()==')
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
del x[0:2]
print(x,'\n') 

print('==使用list.count(obj) 统计某个元素在列表中出现的次数==')
list1 = [123, 456] * 3
print(list1)  # [123, 456, 123, 456, 123, 456]
num = list1.count(123)
print('出现次数为:',num,'\n')  # 3

print('==使用ist.index(x[, start[, end]]) 从列表中找出某个值第一个匹配项的索引位置==')
list1 = [123, 456] * 5
print('从索引0开的第一次出现位置为:',list1.index(123))  
print('从索引1开的第一次出现位置为:',list1.index(123, 1))  
print('从索引3到7中的第一次出现位置为:',list1.index(123, 3, 7),'\n')

print('===使用list.reverse() 反向列表中元素==')
x = [123, 456, 789]
x.reverse()
print('翻转后的结果为',x) 

print('==使用list.sort(key=None, reverse=False) 对原列表进行排序,key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。reverse -- 排序规则,reverse = True 降序, reverse = False 升序(默认)==')
x.sort(reverse=True)
print('排序后的结果为',x)

结果为

==使用append()添加元素,此元素如果是一个 list,那么这个 list 将作为一个整体进行追加==
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', ['Thursday', 'Sunday']] 

==使用extend()添加元素,在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)===
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Thursday', 'Sunday'] 

==list.insert(index, obj) 在编号 index 位置插入 obj==
['Monday', 'Tuesday', 'Sunday', 'Wednesday', 'Thursday', 'Friday'] 

==使用list.remove(obj) 移除列表中某个值的第一个匹配项==
['Tuesday', 'Wednesday', 'Thursday', 'Friday'] 

==使用list.pop([index=-1]) 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值==
Friday 

==使用del var1[, var2 ……] 删除单个或多个对象,如果你要从列表中删除一个元素,且不再以任何方式使用它,就使用del语句;如果你要在删除元素后还能继续使用它,就使用方法pop()==
['Wednesday', 'Thursday', 'Friday'] 

==使用list.count(obj) 统计某个元素在列表中出现的次数==
[123, 456, 123, 456, 123, 456]
出现次数为: 3 

==使用ist.index(x[, start[, end]]) 从列表中找出某个值第一个匹配项的索引位置==
从索引0开的第一次出现位置为: 0
从索引1开的第一次出现位置为: 2
从索引37中的第一次出现位置为: 4 

===使用list.reverse() 反向列表中元素==
翻转后的结果为 [789, 456, 123]
==使用list.sort(key=None, reverse=False) 对原列表进行排序,key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。reverse -- 排序规则,reverse = True 降序, reverse = False 升序(默认)==
排序后的结果为 [789, 456, 123]

5.获取列表中的元素

(1)通过元素的索引值,从列表获取单个元素,注意,列表索引值是从0开始的。
(2)通过将索引指定为-1,可让Python返回最后一个列表元素,索引 -2 返回倒数第二个列表元素,以此类推。
(3)获取切片,通用写法为start : stop : step

  • 情况 1 -== “start :”==以 step 为 1 (默认) 从编号 start 往列表尾部切片
  • 情况 2 - ==": stop"==以 step 为 1 (默认) 从列表头部往编号 stop 切片。
  • 情况 3 - ==“start : stop”==以 step 为 1 (默认) 从编号 start 往编号 stop 切片
  • 情况 4 - "start : stop : step"以具体的 step 从编号 start 往编号 stop 切片。注意最后把 step 设为 -1,相当于将列表反向排列
  • 情况 5 - ==" : "==复制列表中的所有元素(浅拷贝)
    扩展:浅拷贝与深拷贝
  • 浅拷贝会创建新对象,其内容非原对象本身的引用,而是原对象内第一层对象的引用。
    浅拷贝有三种形式:切片操作、工厂函数、copy模块中的copy函数。
    (1)切片操作:b = a[ : ] 或者 b = [ x for x in a ];
    (2)工厂函数:b = list( a );
    (3)copy函数:b = copy.copy( a );
    浅拷贝产生的列表b不再是列表a了,使用is判断可以发现他们不是同一个对象,使用id查看,他们也不指向同一片内存空间。但是当我们使用id(x) for x in a 和 id(x) for x in b来查看a和b 中元素的地址时,可以看到二者包含的元素的地址是相同的。
    在这种情况下,列表a和b是不同的对象,修改列表b理论上不会影响到列表a。
    但是要注意的是,浅拷贝之所以称之为浅拷贝,是它仅仅只拷贝了一层,在列表a中有一个嵌套的list,如果我们修改了它,情况就不一样了
    比如:a[3].append(‘java’)。查看列表b,会发现列表b也发生了变化,这是因为,我们修改了嵌套的list,修改外层元素,会修改它的引用,让它们指向别的位置,修改嵌套列表中的元素,列表的地址并未发生变化,指向的都是用一个位置
  • 深拷贝对一个对象是所有层次的拷贝(递归),内部和外部都会被拷贝过来。
    深拷贝只有一种形式,copy模块中的deepcopy()函数。
    深拷贝和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。因此,它的时间和空间开销要高。
    同样的对列表a,如果使用 b = copy.deepcopy(a),再修改列表b将不会影响到列表a,即使嵌套的列表具有更深的层次,也不会产生任何影响,因为深拷贝拷贝出来的对象根本就是一个全新的对象,不再与原来的对象有任何的关联
  • 浅拷贝与深拷贝相关概念见https://www.runoob.com/w3cnote/python-understanding-dict-copy-shallow-or-deep.html
    https://blog.csdn.net/weixin_38819889/article/details/86476528
    https://blog.csdn.net/qq_42739440/article/details/82183618

【例1】获取切片

print('从step以 step 为 1 (默认) 从编号 start 往列表尾部切片')
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
print(x[3:])  
print(x[-3:]) 
print('=============')

print('以 step 为 1 (默认) 从列表头部往编号 stop 切片')
week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
print(week[:3]) 
print(week[:-3])  
print('=============')

print('以 step 为 1 (默认) 从编号 start 往编号 stop 切片')
week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
print(week[1:3])  
print(week[-3:-1])  
print('=============')

print('以具体的 step 从编号 start 往编号 stop 切片。注意最后把 step 设为 -1,相当于将列表反向排列')
week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
print(week[1:4:2]) 
print(week[:4:2])  
print(week[1::2])  
print(week[::-1])  
print('=============')

print('复制列表中的所有元素(浅拷贝)')
week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
print(week[:])  

结果为

从step以 step 为 1 (默认) 从编号 start 往列表尾部切片
['Thursday', 'Friday']
['Wednesday', 'Thursday', 'Friday']
=============
以 step 为 1 (默认) 从列表头部往编号 stop 切片
['Monday', 'Tuesday', 'Wednesday']
['Monday', 'Tuesday']
=============
以 step 为 1 (默认) 从编号 start 往编号 stop 切片
['Tuesday', 'Wednesday']
['Wednesday', 'Thursday']
=============
以具体的 step 从编号 start 往编号 stop 切片。注意最后把 step 设为 -1,相当于将列表反向排列
['Tuesday', 'Thursday']
['Monday', 'Wednesday']
['Tuesday', 'Thursday']
['Friday', 'Thursday', 'Wednesday', 'Tuesday', 'Monday']
=============
复制列表中的所有元素(浅拷贝)
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']

【例2】赋值、浅拷贝与深拷贝,其中b是a赋值得到的,c是浅拷贝,d是深拷贝
(1)直接赋值:其实就是对象的引用(别名)。
(2)浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。
(3)深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。

import copy
a = [1, 2, 3, 4, ['a', 'b']] #原始对象
 
b = a                       #赋值,传对象的引用
c = copy.copy(a)            #对象拷贝,浅拷贝
d = copy.deepcopy(a)        #对象拷贝,深拷贝
 
a.append(5)                 #修改对象a
a[4].append('c')            #修改对象a中的['a', 'b']数组对象
 
print( 'a = ', a )
print( 'b = ', b )
print( 'c = ', c )
print( 'd = ', d )

结果为

('a = ', [1, 2, 3, 4, ['a', 'b', 'c'], 5])
('b = ', [1, 2, 3, 4, ['a', 'b', 'c'], 5])
('c = ', [1, 2, 3, 4, ['a', 'b', 'c']])
('d = ', [1, 2, 3, 4, ['a', 'b']])

相关资料

  • https://www.runoob.com/python3/python3-tutorial.html
  • https://www.bilibili.com/video/av4050443
  • https://mp.weixin.qq.com/s/DZ589xEbOQ2QLtiq8mP1qQ

练习题

1.列表lst 内容如下 lst = [2, 5, 6, 7, 8, 9, 2, 9, 9] 请写程序完成下列操作: 
在列表的末尾增加元素15;
在列表的中间位置插入元素20;
将列表[2, 5, 6]合并到lst中;
移除列表中索引为3的元素;
翻转列表里的所有元素;
对列表里的元素进行排序,从小到大一次,从大到小一次

分析:充分使用列表的各种内置函数

lst=[2, 5, 6, 7, 8, 9, 2, 9, 9]
lst.append(15)
print('在末尾增加元素15:',lst)

lst.insert(len(lst)//2, 20)
print('在列表的中间位置插入元素20:',lst)

lst.extend([2,5,6])
print('将列表[2, 5, 6]合并到lst中:',lst)

lst.remove(lst[3])
print('移除列表中索引为3的元素:',lst)

lst.reverse()
print('翻转列表里的所有元素:',lst)

lst.sort()
print('从小到大排序:',lst)

lst.sort(reverse=True)
print('从大到小排序:',lst)

结果为

在末尾增加元素15[2, 5, 6, 7, 8, 9, 2, 9, 9, 15]
在列表的中间位置插入元素20[2, 5, 6, 7, 8, 20, 9, 2, 9, 9, 15]
将列表[2, 5, 6]合并到lst中: [2, 5, 6, 7, 8, 20, 9, 2, 9, 9, 15, 2, 5, 6]
移除列表中索引为3的元素: [2, 5, 6, 8, 20, 9, 2, 9, 9, 15, 2, 5, 6]
翻转列表里的所有元素: [6, 5, 2, 15, 9, 9, 2, 9, 20, 8, 6, 5, 2]
从小到大排序: [2, 2, 2, 5, 5, 6, 6, 8, 9, 9, 9, 15, 20]
从大到小排序: [20, 15, 9, 9, 9, 8, 6, 6, 5, 5, 2, 2, 2]

2.问题描述:
lst = [1, [4, 6], True]
请将列表里所有数字修改成原来的两倍

方法一:直接修改

lst = [1, [4, 6], True]
lst[0]=lst[0]*2
lst[1][0]=lst[1][0]*2
lst[1][1]=lst[1][1]*2
print(lst)

方法二:通过函数实现

def double_list(lst):
    for index,item in enumerate(lst):   
    #enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中
        if isinstance(item,bool): 
        #判断item是否为bool类型,如果是则跳转到下一个字符,isinstance作用和type一样,区别在于isinstance会考虑继承
            continue
        if isinstance(item, (int, float)):
            lst[index]*=2
        if isinstance(item,list):
            double_list(item)


if __name__ == '__main__':
    lst = [1, [4, 6], True]
    double_list(lst)
    print(lst)

3.leetcode 852题 山脉数组的峰顶索引
我们把符合下列属性的数组 A 称作山脉:

A.length >= 3
存在 0 < i < A.length - 1 使得A[0] < A[1] < … A[i-1] < A[i] > A[i+1] > … > A[A.length - 1]
给定一个确定为山脉的数组,返回任何满足 A[0] < A[1] < … A[i-1] < A[i] > A[i+1] > … > A[A.length - 1] 的 i 的值。
现在,给定一个山脉数组,求顶峰索引。

思路:
(1)山脉数组的特点是在到达山脉峰顶前,每个元素都比右侧的元素小,过了峰顶之后,每个元素都比
右侧元素大。
(2)对数组k进行遍历,当k[index] < k[index+1] 不成立时,说明可能到达峰顶了,记录当前这个索引
index, 接下来要判断index的值,如果index等于0,说明k[0] index 等于len(k)-1, 说明倒数第2个数元素小于倒数第1个元素,显然也不是山脉数组。
(3)如果index的值符合要求,也只能说明在index之前,是一个爬坡的过程,过了index之后,需要再用一个
循环继续遍历,如果lst[index]>lst[index+1] 不成立,则不是山脉数组,前半段,后半段的判断简单一
些,不涉及到峰顶索引位置的判断。

# coding=utf-8
def is_mountain_lst(lst):
# 如果长度小于3,不符合定义
    if len(lst) < 3:
        return False
    
    # 第一个循环找到发生转折的地方
    index = 0
    while index < len(lst)-1:
        if lst[index] < lst[index+1]:
            index += 1
        else:
        # 当前元素比右侧元素小,说明到达峰顶了,停止循环
            break
            
            
    # 如果index == 0,说明lst[0] < lst[1] 不成立,显然不是山脉数组
    # 如果index == len(lst) -1, 说明倒数第2个数小于倒数第一个数,显然也不是山脉数组
    if index == 0 or index== len(lst) -1:
        return False
    # 接下来要判断从index 开始到列表末尾,是不是都满足lst[index] > lst[index+1]
    while index < len(lst)-1:
        if lst[index] > lst[index+1]:
            index += 1
        else:
            return False
    return True

if __name__ == '__main__':
    print( is_mountain_lst([1, 2]))
    print( is_mountain_lst([1, 2, 3]))
    print( is_mountain_lst([1, 3, 4, 5, 3]))
    print( is_mountain_lst([1, 2, 4, 6, 4, 5]))

 
 
 

元组

「元组」定义语法为:(元素1, 元素2, …, 元素n)

1.创建和访问一个元组

(1)Python 的元组与列表类似,不同之处在于tuple被创建后就不能对其进行修改
(2)元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运算符使用
(3)创建元组可以用小括号 (),也可以什么都不用
【例1】元组的两种表示方法

t1 = (1, 10.31, 'python')
t2 = 1, 10.31, 'python'
print(t1, type(t1))
print(t2, type(t2))

结果为

(1, 10.31, 'python') <class 'tuple'>
(1, 10.31, 'python') <class 'tuple'>

【例2】元组只包含一个元素时,需要在元素后面加逗号

x = (1)
print(type(x))  # 
x = 2, 3, 4, 5
print(type(x))  # 
x = []
print(type(x))  # 
x = ()
print(type(x))  # 
x = (1,)
print(type(x))  # 

【例3】创建二维元素

x = (1, 10.31, 'python'), ('data', 11)
print(x)
# ((1, 10.31, 'python'), ('data', 11))

print(x[0])
# (1, 10.31, 'python')
print(x[0][0], x[0][1], x[0][2])
# 1 10.31 python

print(x[0][0:2])
# (1, 10.31)

2.更新和删除一个元组

(1)更新元组

  • 元组中的元素值是不允许修改的,但我们可以对元组进行连接组合
  • 如果元组中的某个元素时可以更改的,那么我们可以更改其元素
    【例1】元组t1中包含列表元素,而列表是可以更改的
t1 = (1, 2, 3, [4, 5, 6])
print(t1)  # (1, 2, 3, [4, 5, 6])

t1[3][0] = 9
print(t1)  # (1, 2, 3, [9, 5, 6])

(2)删除元组
元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组,如下实例:

tup = ('physics', 'chemistry', 1997, 2000)
 
print tup
del tup
print "After deleting tup : "
print tup

但是这种情况下一般会报错,因为元组已经被删除了,没有了这个变量,自然无法输出

3.元组相关的操作符

【python学习笔记】task04 列表、元组和字符串_第2张图片

t1 = (123, 456)
t2 = (456, 123)
t3 = (123, 456)

print(t1 == t2)  # False
print(t1 == t3)  # True

t4 = t1 + t2
print(t4)  # (123, 456, 456, 123)

t5 = t3 * 3
print(t5)  # (123, 456, 123, 456, 123, 456)

t3 *= 3
print(t3)  # (123, 456, 123, 456, 123, 456)

print(123 in t3)  # True
print(456 not in t3)  # False

4.元组内置函数

点击方法查看详情

方法 描述
count() 返回元组中指定值出现的次数
index() 在元组中搜索指定的值并返回它被找到的位置

【例子】统计python出现的次数,返回10.31的索引

t=(1,10.31,'python')
print(t.count('python')) #1
print(t.index(10.31)) #1

5.解压元组

(1)解压(unpack)一维元组(有几个元素,左边定义几个变量)

t = (1, 10.31, 'python')
(a, b, c) = t
print(a, b, c)
# 1 10.31 python

(2)解压二维元组(按照元组里的元组结构来定义变量)

t = (1, 10.31, ('OK', 'python'))
(a, b, (c, d)) = t
print(a, b, c, d)
# 1 10.31 OK pytho

(3)如果只想要元组中的几个元素,采用通配符==*==来实现,如下例中将不想要的元素都给了rest

t = 1, 2, 3, 4, 5
a, b, *rest, c = t
print(a, b, c)  # 1 2 5
print(rest)  # [3, 4

也可以不定义rest,直接用==_==代替

t = 1, 2, 3, 4, 5
a, b, *_ = t
print(a, b)  # 1 2

拆包相关概念见https://www.cnblogs.com/shen-qiang/p/8983782.html

练习题

1.元组概念
写出下面代码的执行结果和最终结果的类型
(1, 2)*2
(1, )*2
(1)*2

分析:通过代码来查看,从输出结果中可以看出(1, 2)*2和(1,
)*2是元组,(1)*2是一个整型数据,这与元组的定义有关,元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运算符使用

a=(1, 2)*2
b=(1, )*2
c=(1)*2
print(a,type(a))
#(1, 2, 1, 2) 
print(b,type(b))
#(1, 1) 
print(c,type(c))
#2 

2.拆包过程是什么?
a, b = 1, 2
上述过程属于拆包吗?
可迭代对象拆包时,怎么赋值给占位符?

(1)拆包: 对于函数中的多个返回数据, 去掉元组, 列表 或者字典 直接获取里面数据的过程.
(2)属于,创建元组可以用小括号 (),也可以什么都不用,所以该过程属于对元组的拆包
(3)对于我们不想接收的元素,我们可以⽤占位符 _ 接收

 
 
 
 

字符串

1.字符串的定义

(1)python 中的字符串字面量由单引号或双引号括起。

t1 = 'i love Python!'
print(t1, type(t1))
# i love Python! 

t2 = "I love Python!"
print(t2, type(t2))
# I love Python! 

print(5 + 8)  # 13
print('5' + '8')  # 5

(2)转移字符的表示
【python学习笔记】task04 列表、元组和字符串_第3张图片

  • 原始字符串只需要在字符串前面加一个英文字母r即可,不需要繁琐的添加转义符
print(r'C:\Program Files\Intel\Wifi\Help')  
# C:\Program Files\Intel\Wifi\Help
  • 三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符(但不会显示)。
para_str = """这是一个多行字符串的实例
多行字符串可以使用制表符
TAB ( \t )。
也可以使用换行符 [ \n ]。
"""
print(para_str)
# 这是一个多行字符串的实例
# 多行字符串可以使用制表符
# TAB (    )。
# 也可以使用换行符 [
#  ]。

2.字符串的切片与拼接

(1)从0开始
(2)切片通常写成 start:end 这种形式,包括「start 索引」对应的元素,不包括「end索引」对应的元素。
(3)索引值可正可负,正索引从 0 开始,从左往右;负索引从 -1 开始,从右往左。

str1 = 'I Love LsgoGroup'
print(str1[:6])  # I Love
print(str1[5])  # e
print(str1[:6] + " 插入的字符串 " + str1[6:])  
# I Love 插入的字符串  LsgoGroup

s = 'Python'
print(s)  # Python
print(s[2:4])  # th
print(s[-5:-2])  # yth
print(s[2])  # t
print(s[-1])  # n

3.字符串内置函数

只列举部分常见的,更多的参照https://www.runoob.com/python/python-strings.html

方法 描述
string.capitalize() 把字符串的第一个字符大写
string.center(width) 返回一个原字符串居中,并使用空格填充至长度 width 的新字符串
string.count(str, beg=0, end=len(string)) 返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数
string.decode(encoding=‘UTF-8’, errors=‘strict’) 以 encoding 指定的编码格式解码 string,如果出错默认报一个 ValueError 的 异 常 , 除非 errors 指 定 的 是 ‘ignore’ 或 者’replace’
string.encode(encoding=‘UTF-8’, errors=‘strict’) 以 encoding 指定的编码格式编码 string,如果出错默认报一个ValueError 的异常,除非 errors 指定的是’ignore’或者’replace’
string.endswith(obj, beg=0, end=len(string)) 检查字符串是否以 obj 结束,如果beg 或者 end 指定则检查指定的范围内是否以 obj 结束,如果是,返回 True,否则返回 False.
string.expandtabs(tabsize=8) 把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 8。
string.find(str, beg=0, end=len(string)) 检测 str 是否包含在 string 中,如果 beg 和 end 指定范围,则检查是否包含在指定范围内,如果是返回开始的索引值,否则返回-1
string.format() 格式化字符串
string.index(str, beg=0, end=len(string)) 跟find()方法一样,只不过如果str不在 string中会报一个异常.
string.isalnum() 如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False
string.isalpha() 如果 string 至少有一个字符并且所有字符都是字母则返回 True,否则返回 False
string.isdecimal() 如果 string 只包含十进制数字则返回 True 否则返回 False.
string.isdigit() 如果 string 只包含数字则返回 True 否则返回 False.
string.isnumeric() 如果 string 中只包含数字字符,则返回 True,否则返回 False
string.lower() 转换 string 中所有大写字符为小写.
string.replace(str1, str2, num=string.count(str1)) 把 string 中的 str1 替换成 str2,如果 num 指定,则替换不超过 num 次.
string.rfind(str, beg=0,end=len(string) ) 类似于 find()函数,不过是从右边开始查找.
string.rindex( str, beg=0,end=len(string)) 类似于 index(),不过是从右边开始.
string.split(str="", num=string.count(str)) 以 str 为分隔符切片 string,如果 num 有指定值,则仅分隔 num+ 个子字符串
string.splitlines([keepends]) 按照行(’\r’, ‘\r\n’, \n’)分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。
string.swapcase() 翻转 string 中的大小写
string.upper() 转换 string 中的小写字母为大写
string.zfill(width) 返回长度为 width 的字符串,原字符串 string 右对齐,前面填充0

4.字符串格式化

(1)format 格式化函数

str8 = "{0} Love {1}".format('I', 'Lsgogroup')  # 位置参数
print(str8)  # I Love Lsgogroup

str8 = "{a} Love {b}".format(a='I', b='Lsgogroup')  # 关键字参数
print(str8)  # I Love Lsgogroup

str8 = "{0} Love {b}".format('I', b='Lsgogroup')  # 位置参数要在关键字参数之前
print(str8)  # I Love Lsgogroup

str8 = '{0:.2f}{1}'.format(27.658, 'GB')  # 保留小数点后两位
print(str8)  # 27.66GB

(2)python字符串格式化符号

符号 描述
%c 格式化字符及其ASCII码
%s 格式化字符串,用str()方法处理对象
%r 格式化字符串,用rper()方法处理对象
%d 格式化整数
%o 格式化无符号八进制数
%x 格式化无符号十六进制数
%X 格式化无符号十六进制数(大写)
%f 格式化浮点数字,可指定小数点后的精度
%e 用科学计数法格式化浮点数
%E 作用同%e,用科学计数法格式化浮点数
%g 根据值的大小决定使用%f或%e
%G 作用同%g,根据值的大小决定使用%f或%E
print('%c' % 97)  # a
print('%c %c %c' % (97, 98, 99))  # a b c
print('%d + %d = %d' % (4, 5, 9))  # 4 + 5 = 9
print("我叫 %s 今年 %d 岁!" % ('小明', 10))  # 我叫 小明 今年 10 岁!
print('%o' % 10)  # 12
print('%x' % 10)  # a
print('%X' % 10)  # A
print('%f' % 27.658)  # 27.658000
print('%e' % 27.658)  # 2.765800e+01
print('%E' % 27.658)  # 2.765800E+01
print('%g' % 27.658)  # 27.658
text = "I am %d years old." % 22
print("I said: %s." % text)  # I said: I am 22 years old..
print("I said: %r." % text)  # I said: 'I am 22 years old.'

(3)格式化操作辅助指令

符号 功能
m.n m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话)
- 用作左对齐
+ 在正数前面显示加号( + )
# 在八进制数前面显示零(‘0’),在十六进制前面显示’0x’或者’0X’(取决于用的是’x’还是’X’)
0 显示的数字前面填充’0’而不是默认的空格
print('%5.1f' % 27.658)  # ' 27.7'
print('%.2e' % 27.658)  # 2.77e+01
print('%10d' % 10)  # '        10'
print('%-10d' % 10)  # '10        '
print('%+d' % 10)  # +10
print('%#o' % 10)  # 0o12
print('%#x' % 108)  # 0x6c
print('%010d' % 5)  # 0000000005

相关资料

  • https://www.runoob.com/python3/python3-tutorial.html
  • https://www.bilibili.com/video/av4050443
  • https://mp.weixin.qq.com/s/DZ589xEbOQ2QLtiq8mP1qQ

练习题

1、字符串函数回顾
怎么批量替换字符串中的元素?
怎么把字符串按照空格进⾏拆分?
怎么去除字符串⾸位的空格?

(1)批量替换元素:replace(old, new [, max]) 把 将字符串中的old替换成new,如果max指定,则替换不超过max次
(2)按照空格进行拆分:split(str="", num) 不带参数默认是以空格为分隔符切片字符串,如果num参数有设置,则仅分隔num个子字符串,返回切片后的子字符串拼接的列表。
(3)去除字符串首位的空格:lstrip([chars]) 截掉字符串左边的空格或指定字符。

2.实现isdigit函数
题目要求
实现函数isdigit, 判断字符串里是否只包含数字0~9

def isdigit(string):
    """
    判断字符串只包含数字
    :param string:
    :return:
    """
    # your code here
    pass

思路:只包含数字的话,那么其每一位应该都大于等于’0’且小于等于‘9’

def isdigit(string):
    """
    判断字符串只包含数字
    :param string:
    :return:
    """
    # your code here
    n=0
    for i in a:
        if '0'<=i and i<='9':
            n=n+1
            continue
        else:
            break
    if n==len(string):
        print('只包含数字')
    else:
        print('不只包含数字')

3.3、leetcode 5题 最长回文子串

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例:
输入: “babad”
输出: “bab”
输入: “cbbd”
输出: “bb”

class Solution:
   def longestPalindrome(self, s: str) -> str:
          
    # your code here

方法一:动态规划
对于一个字串而言,如果它是回文串,并且长度大于二,那么将他的收尾两个字母去除之后,它仍然是个回文串,或者或已知bcb是回文串,那么在首尾加入两个一样的字母a构成的abcba仍然是回文串,按照这个思路,可以用动态规划的思想解决此问题。
假设p(i,j)表示字符串s的第i个到j个字母组成的串(下文表示成s[i:j])是否为回文串
在这里插入图片描述
这里其他情况包括两种可能性:
(1)s[i:j]本身不是一个回文串
(2)i>j,此时 s[i;j] 本身不合法
那么动态规划的转移方程为: p(i,j)=p(i+1,j-1)^(si==sj)
也就是说,只有 s[i+1:j-1]s[i+1:j−1] 是回文串,并且 s 的第 i和 j个字母相同时,s[i:j]s[i:j] 才会是回文串

class Solution:
    def longestPalindrome(self, s: str) -> str:     
    # your code here
        n=len(s)
        dp=[[False]*n for _ in range(n)]#初始化n*n列的False数组
        ans=''#用来存储回文串
        for l in range(n):#枚举字串的长度l+1(因为range(n)是从0到n-1)
            for i in range(n):#枚举字串的起始位置i
                j=i+l
                if j>=len(s):
                    break
                if l==0:#枚举字串长度为1那么一定是回文的
                    dp[i][j]=True
                elif l==1:#枚举字串长度为2要看s[i]和s[j]是否相等,若相等则是回文的
                    dp[i][j]=(s[i]==s[j])
                else:
                    dp[i][j]=(dp[i + 1][j - 1] and s[i] == s[j])#如果去掉头尾是回文且s[i]和s[j]是相等那么是回文
                if dp[i][j] and l+1>len(ans):
                    ans=s[i:j+1]
        return ans

测试

from typing import List
a='babad'
S=Solution()
print(S.longestPalindrome(a))

方法二:中心扩展法
【python学习笔记】task04 列表、元组和字符串_第4张图片
可以发现,所有的状态在转移的时候的可能性都是唯一的。也就是说,我们可以从每一种边界情况开始「扩展」,也可以得出所有的状态对应的答案,该方法的本质即枚举所有的「回文中心」并尝试「扩展」,直到无法扩展为止,此时的回文串长度即为此「回文中心」下的最长回文串长度。对所有的长度求出最大值,即可得到最终的答案

class Solution {
    public String longestPalindrome(String s) {
        if (s == null || s.length() < 1) return "";
        int start = 0, end = 0;
        for (int i = 0; i < s.length(); i++) {
            int len1 = expandAroundCenter(s, i, i);
            int len2 = expandAroundCenter(s, i, i + 1);
            int len = Math.max(len1, len2);
            if (len > end - start) {
                start = i - (len - 1) / 2;
                end = i + len / 2;
            }
        }
        return s.substring(start, end + 1);
    }

    private int expandAroundCenter(String s, int left, int right) {
        int L = left, R = right;
        while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) {
            L--;
            R++;
        }
        return R - L - 1;
    }
}

以上方法参照https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zui-chang-hui-wen-zi-chuan-by-leetcode-solution/

你可能感兴趣的:(python学习笔记)