实用Python程序设计MOOC-第五章字符串和元组

实用Python程序设计MOOC-第五章字符串和元组

[TOC]

实用Python程序设计MOOC-第五章字符串和元组

Python变量的指针本质

Python的数据类型

基本数据类型

int,float,complex

组合数据类型

字符串:str
元组:tuple
列表:list
字典:dict
集合:set

isinstance函数

isinstance(x, y) 函数查询数据x是否是类型y

1
2
3
4
5
a = "1233"
print(isinstance(a, str)) #>>True
print(isinstance(a, int)) #>>False
b = (1, 3,)
print(isinstance(b, tuple)) #>>True

len函数

len函数可以用来求组合数据类型的元素个数 (长度)

1
2
3
4
5
print(len("12345"))	#>>5	求字符串十
print(len([1,2,3,4]) #>>4 求列表长度
print(len((1,2,3))) #>>3 求元组长度
print(len({1,2,3})) #>>3 求集合元素个数
print(len({'tom':2, 'jack':3})) #>>求字典元素个数

Python变量的指针本质

  • Pyhton中的变量都是指针
  • Python中所有可赋值的东西,即可以出现在赋值号”=”左边的东西,都是指针
  • 指针即代表内存单元的地址
  • 将指针称作”箭头”, 更容易理解。所有变量都是箭头,指向内存某处

  • 对变量进行赋值的本质,就是让该变量(箭头)指向某个地方

1
2
a = 3	#a → 3
b = 4 #b → 4
  • 用一个变量对另一个变量赋值意味着让两个变量指向同一个地方
1
2
a = b	#a ↘ 3
#b → 4

is运算符和==的区别

a is b 为True说a和b指向同一个地方

a == b为True说明a和b指向的地方放的的东西相同,但是a和b不一定指向相同的地方

a = b 会使得a和b指向同一个地方

x is y 表示x和y是否指向同一个地方
x == y 表示x和y的内容是否相同

1
2
3
4
5
6
7
8
9
10
11
12
a = [1,2,3,4]	#a → [1,2,3,4]
b = [1,2,3,4] #b → [1,2,3,4]
print(a == b) #>>True
print(a is b) #>>False

c == a
print(a == c) #>>True
print(a is c) #>>True

a[2] = "ok"
print(c) #>>[1, 2, 'ok', 4]
#因为a和c指向同一个地方,所以修改a[2],c[2] 也变。a[2]和c[2]是同一个东西
  • 对int,float,complex,str,tuple类型的变量a和b,只需关注a == b是否成立,关注a is b是否成立无意义。因这些数据本身都不会更改,不会产生a指向的东西改了b指向的东西也跟着变的情况。数据类型不可能改变的。

  • 对list,dict,set类型的变量a和b,a == ba is b的结果都需要关注。因这些数据本身会改变。改别了a指向的内容,说不定b指向的内容也变了。该数据类型可能改变的。

列表元素的指针本质

列表的元素也可以赋值,因此也是指针

1
2
a = [1,2,3,4]
b = [1,2,3,4]

字符串的转义字符

转义字符

\及其后面的某些字符会构成转义字符,即两个字符当一个字符看

1
print ("hello\nworld\tok\"1\\2") #\n \t \" \\都是“转义字符”代表换行,制表符,双引号,斜杠

输出:

1
2
hello
world ok"1\2

字符,包括\n这样的转义字符,只能出现在字符串里面,必须用引号括起来!

print(a\nb) 不合法,不会打出a的值,然后换行,再打出b的值

  • 规定 \ 不转义的字符串

print(r'ab\ncd') #>>ab\ncd

r表示字符串里面的\就是\,不会和后面的字符合并起来看待

字符串的切片(子串)

  • 字符串的切片( 也叫子串,即连续的一部分)

a[x:y]表示字符串a里从下标x到下标y那一部分的子串(不包括下标y的那个字符),左闭右开

1
2
3
4
5
6
7
a = "ABCD"
print(a[1:2]) #>>B 区间是`左闭右开`,终点不算
print(a[0:-1]) #>>ABC
print(a[-3:-1]) #>>BC
print(a[2:]) #>>CD 终点省略就是一直取到最后一个字符
print(a[:3]) #>>ABC 起点省略就是从头开始取
print("abcd"[2:3]) #>>c

a[x:y:z]表示,从a[x]取到a[y] (a[y]不算),每z个字符取一个,最后拼起来。
z为负数则代表倒着取,左开右闭
x, y可以省略。x, y全省略表示从头取到尾或从尾取到头

1
2
3
4
print("1234"[3:1:-1]) #>>43
print("abcde"[::-1]) #>>edcba 可用于反转字符串
print("12345678"[1:7:2]) #>>246
print("12345678"[7:1:-2]) #>>864

字符串切片的用法也适用于元组和列表!

字符串的分割(split)

split函数详解

s.split(x) 用字符串x做分隔符分割字符串s,得到分隔后的列表

两个相邻分隔符之间会被分隔出一个空串

1
2
3
4
a = "12..34.5346...a"
print(a.split("..")) #>> ['12', '34.5346','.a']
print(a.split(".")) #>> ['12', '','34', '5346`, '', '', 'a']
print(a.split("34")) #>> ['12..', ''.5', '6...a']

字符串高级分割

  • 用多个分隔串进行分割
1
2
3
4
5
6
7
8
9
import re	#正则表达式包
a = 'Beautiful, is; better*than\nugly'
print(re.split(';| |,|\*|\n', a)) #分隔串用|隔开]
#';'
#' '
#','
#'*' \*代表*
#'\n' 都被看做分隔符
#>> ['Beautiful', '', 'is', '', 'better', 'than', 'ugly']

两个相邻的分隔串之间,会隔出一个空串

字符串的函数

  • count求子串出现次数
1
2
s = 'thisAAbb AA'
s.count('AA') #返回2,AA出现2次
  • len字符串长度
1
2
s = '1234'
len(s) #4
  • upperlower转大写、小写
1
2
3
s = "abc"
print(s.upper()) #>>ABC
print(s) #>>abc
  • findrfindindexrindex

在字符串中查找子串,返回找到的位置(下标)。
找不到的话,find返回-1,index引发异常

1
2
3
4
5
6
7
8
s = "1234abc567abc12"
print(s.find("ab")) #>>4,"ab"第一次出现在下标4
print(s.rfind("ab")) #>>10
#find从头开始找,rfind从尾巴开始找。返回第一个找到的位置
try:
s.index("afb") #找不到"afb"因此会产生异常
except Exception as e:
print(e) #>>substring not found
  • find还可以指定查找起点
1
2
s = "1234abc567abc12"
print(s.find("12", 4)) #>>13指定从下标4处开始查找

如果想要找到所有的子串,需要写一个循环,规定指针

  • replace替换
1
2
3
4
5
s = "1234abc567abc12"
b = s.replace("abc", "FGHI") #b由把s里所有abc换成FGHI而得
print(b) #>>1234FGHI567FGHI12
print(s) #>>1234abc567abc12
print(s.replace("abc", "")) #>>123456712
  • isdigit()islower()isupper() 判断字符串是否是数,是否全是小写,是否全是大写等
  • startswithendswith 判断字符串是否以某子串开头、结尾
1
2
3
4
5
print("123.4".isdigit())	#>>False
print("123".isdigit()) #>>True
print("a123.4".isdigit()) #>>False
print("Ab123".islower()) #>>False
print("ab123".islower()) #>>True
  • strip() 返回除去头尾空白字符(空格,\r \t \n)后的字符串
  • lstrip() 返回除去头部(左端)空白字符后的字符串
  • rstrip() 返回除去尾部(右端)空白字符后的字符串
1
2
print(" \t12 34 \n'".strip())	#>>12 34
print(" \t12 34 5".lstrip()) #>>12 34 5

strip(s)lstrip(s)rstrip(s)返回除去两端、左端、右端在s中出现的字符后的字符串

1
2
3
4
print( "takeab \n".strip("ba \n"))	#>>take
#去除两端'b', 'a', ' ', '\n'
print( "cd\t12 34 5".lstrip("d\tc") ) #>>12 34 5
#去除左端'd', '\t', 'c'

字符串的编码和格式化

字符串的编码在内存中的编码是unicode的,虽然写入文件时可能是gbk或者utf-8的

1
2
3
4
print(ord("a"))	#>>97
print(ord("好")) #>>22920
print(chr(22900)) #>>奴
print(chr(97)) #>>a

字符串格式化

1
2
3
4
5
x = "He1lo {0} {1:10}, you get ${2:0.4f}".format("Mr.", "Jack", 3.2)
print(x) #>>Hello Mr. Jack , you get $3.2000

x = "Hello {0} {1:>10}, you get ${2:0.4f}".format("Mr.", "Jack", 3.2)
print(x) #Hello Mr. Jack, you get $3.2000

{序号:宽度.精度 类型} 宽度可以是0
> : 右对齐
< : 左对齐
^ : 中对齐

{0:>10.4f}表示第0项是小数,以宽度至少是10字符,右对齐(宽度不足时空格补在左边),保留小数点后面4位的方式输出。

1
print("Today is %s.%d." % ('May', 21))	#Today is May.21.

元组

  • 一个元组由数个逗号分隔的值组成,前后可加括号
  • 元组不能修改,即不可增删元素,不可对元素赋值,不可修改元素顺序(如排序)
1
2
3
4
5
6
7
8
t = 12345, 54321, 'he1lo!'	#t是一个元组
print(t[0]) #>>12345
print(t) #>>(12345, 54321, 'hello!')
u = t, (1, 2, 3, 4, 5) #u有两个元素,都是元组
print(u) #>>((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
print(u[0][1]) #>>54321
print(u[1][2]) #>>3
t[0] = 88888 #运行错误,元组的元素不能赋值
  • 元组的元素的内容有可能被修改。
    例如,如果元素是列表,就可以修改该列表
1
2
3
4
5
v = ("he11o", [1, 2, 3], [3, 2, 1]) #[1, 2, 3]是列表
v[1] = 32 #运行错误,元组元素不可修改成指向别的
v[1][0] = 'world' #可以
print(v) #>>('hello', ['world', 2, 3], [3, 2, 1])
print(len(v)) #>>3求长度,

元组元素的指针本质

  • 元组的元素都是指针。元组元素不可修改,是指不可改变元组元素的指向,但是元组元素指向的内容,是有可能被修改的

所谓的元组元素不可改成别的,类似于组建了一只球队,规定球队人员不可更改。但是队员换个发型,增加体重,受伤缺胳膊少腿了,都是可以的

单元素的元组

1
2
3
4
5
6
empty = ()	#空元组
singleton = 'hello', #注意末尾的,如果没有,就不是元组而是字符串了
print(len(empty)) #>>0
print(len(singleton)) #>>1
x = ('hello',) #无逗号则x为字符串
print(x) #>>('hello',)

用下标访问元组,以及元组切片

用法和字符串一样

1
2
3
4
5
6
tup1 = ('Google', 'Runoob', 1997, 2000)
tup2 = (1, 2, 3, 4, 5, 6, 7)
print(tup1[0]) #>>Google
print(tup2[1:5]) #>>(2, 3, 4, 5)
print(tup2[::-1]) #>>(7, 6, 5, 4, 3, 2, 1)
print(tup2[-1:0:-2]) #>>(7, 5, 3)

可以对元组进行连接组合

1
2
3
4
5
6
7
8
tup1 = (12, 34.56);
tup2 = ('abc', 'xyz')

#创建一个新的元组
tup3 = tup1 + tup2;
print(tup3) #>>(12, 34.56, 'abc', 'xyz')
tup3 += (10, 20) #等价于tup3 = tup3 + (10, 20), 新建了一个元组
print(tup3) #>>(12, 34.56, 'abc', 'xyz', 10, 20)

元组运算和迭代

1
2
3
4
5
x = (1, 2, 3) * 3
print(x) #>>(1, 2, 3, 1, 2, 3, 1, 2, 3)
print(3 in (1, 2, 3)) #>>True
for i in (1, 2, 3):
print(i, end = "") #>>123

元组赋值

1
2
3
4
5
6
7
8
9
x = (1, 2, 3)
b = x
print(b is x) # true is 表示两个操作数是否指向同一个东西,即是否是同一个对象
# 指针指向同一个地方

x += (100,) #等价于x = x + (100,)新建了一个元组
# 执行完之后x和b不在指向同一个指针
print(x) #(1, 2, 3, 100)
print(b) #(1, 2, 3)

元组比大小

  • 两个元组比大小,就是逐个元素比大小,直到分出胜负
  • 如果有两个对应元素不可比大小,则出runtime error
1
2
3
4
print((1, 'a', 12 ) < (1, 'b', 7))	#>>True
print((1, 'a') < (1, 'a', 13)) #>>True
print((2, 'a') > (1, 'b', 13)) #>>True
print((2, 'a') < ('ab', 'b', 13) ) #runtime error
1
2
3
4
5
6
t = (1, [2, 3], 4, 5)

t[0] = 2
t = ("a", 2, 3) #可执行
t[1][0] = "a" #可执行
t += (1, 2) #可执行

重点例题

1
2
3
4
5
6
a = [1, 2, 3]
b = (a, a) #([1, 2, 3], [1, 2, 3])
b[0][1] = 100 #([1, 100, 3], [1, 100, 3])
#直接修改了a的内存空间
print(a, b)
#[1, 100, 3], ([1, 100, 3], [1, 100, 3])

用元组(列表)取代复杂分支结构

  • 输入1-7,输出星期几
1
2
3
4
5
6
weekdays = "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
n = int(input())
if n > 7 or n < 1:
print("Illegal")
else:
print(weekdays[n - 1])

万年历

  • 例题
    已知2012年1月25日是星期三,编写一个程序,输入用”年月日”表示的一个2012年1月25日以后的期,输出该日期是星期几(星期天输出0)。

  • Sample Input
    2015 11 02

  • Sample Output
    1

  • 思路

2012年1月22日是星期天。算出给定日期是从改天起过了x天,然后输出x%7

  • 代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
monthDays = [-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]	#十二个月的天数
days = 0 #从2012-01-22开始过了多少天
lst = input().split()
year, month, date = int(lst[0]), int(lst[1]), int(lst[2])

for y in range(2012, year): #先累加过掉的整年的天数
if y%4 == 0 and y%100 != 0 or y%400 == 0: #闰年
days += 366
else:
days += 365

if year%4 ==0 and year%100 != 0 or year%400 == 0:
monthDays[2] = 29

for i in range (1, month):#再累加year那年过掉的整月的天数
days += monthDays [i]

days += date #累加year年month那个月的天数
days -= 22 #2012年1月22日是星期天。扣掉2012年的前22天
print(days % 7) #星期天算一周的第0天
  • 下面的方法可以更快算出过掉的整年的总天数,不必逐年累加
1
2
3
4
5
days = 0
days += (year - 2012) * 365
if year > 2012 :
days += (year - 2012 - 1) // 4 +1 #补上闰年多的一天
days -= (year - 2000 - 1) // 100 - (year - 2000 - 1) // 400 #扣掉把100的整数倍都当作闰年而多加的天数
文章作者: HibisciDai
文章链接: http://hibiscidai.com/2022/09/30/实用Python程序设计MOOC-第五章字符串和元组/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 HibisciDai
好用、实惠、稳定的梯子,点击这里