str
str是Python内置的一种数据类型,称为字符串。所谓字符串,就是由零个或多个字符组成的有限序列,他是一个不可变量。
-
str可进行的操作
str1 = 'hello,world!'
字符串首字母大写
# 只会把整个字符串的首字母变大写
str1.capitalize() # Hello,world!
# 所有单词的首字母都变成大写
str1.title() # Hello,World!
子符串变全大写
str1.upper()
字符串变全小写
str1.lower()
判断字符串是否是全小写
str1.islower()
查找 find - 若查找的内容存在,返回内容所在位置的索引,不存在返回 -1;
index - 若查找的内容不存在,会报错
str1.find('or') # True
str1.find('shit') # False
str1.index('shit') # 程序报错
字符串是否以某字符开头
str1.startswith('he')
str1.startswith('He')
字符串是否以某字符结尾,长用于查看文件类型
str1.endswith('exe')
在字符串左右填充*字符,字符串居中,共50个字符
str1.center(50, '*')
字符串右对齐,在左填充*
str1.rjust(50, '*')
字符串左对齐,在右填充*
str1.ljust(50, '*')
str2 = 'abcde123456'
判断字符串是否由数字组成
print(str2.isdigit())
判断字符串是否由字母组成
print(str2.isalpha())
判断字符串是否由数字和字母组成
print(str2.isalnum())
从0开始取,取到1
print(str2[:2]) # ab
取某个位置上的字符,从0开始数,如取c,则输入2
print(str2[2])
取多个字符,如取cde,则是第2-4个字符,输入2:5,从2开始取,取到5-1=4
print(str2[2:5])
从第二个开始,取到最后
print(str2[2:])
从第2个开始取,每2个取1个
print(str2[2::2])
从第0个开始取,每2个取1个
print(str2[::2])
从最后一个开始往前面取
print(str2[::-1])
从后面开始取,最后一个为-1,如取6,输入-1
print(str2[-1])
从后面取多个字符,取65
print(str2[-1:-3, -1])
取45
print(str2[-3:-1])
str3 = ' jjhggs@163.com '
去掉左右两边的空格,此处的strip方法没有副作用,str3字符串是不变的
print(str3.strip())
去掉右边的空格
print(str3.rstrip())
去掉左边的空格
print(str3.lstrip())
str4 = 'dgsa dshgd'
替换字符串中某个字符
print(str.replace(' ', '') # 把字符串中的空格替换为空,相当于删除空格 - dgsadshgd
print(str.replace('d', 'a')) # 把字符串中的d变为a - agsa ashga
list
list是Phthon内置的一种数据类型,称为列表。列表是一种有序的集合,列表中的每一个元素都有自己的索引(下标),索引从0开始,根据索引和元素值可以对列表进行增加、删除等操作。
-
定义一维list
列表用[ ]表示,列表中的元素可以是不同数据类型,但在实际情况中,一般都是同类型数据,并且强烈建议列表中放同类型的数据。定义列表有多种方式,如下:
不常用的写法:
list1 = [0, 3, 4, 6, 98, 56]
list2 = list(ranger(1, 10)) # 生成一个1-9的列表
常用的写法:
-
生成式
用列表的生成表达式语法创建列表容器,用这种语法创建列表之后,元素已经准备就绪,所以需要耗费较多的内存空间,但需要数据时,取数据速度快
# 生成一个1-9的列表
list3 = [x ** 2 for x in range(1, 10)] # 生成一个1的平方到9的平方的列表
-
生成器
这里得到的不是一个列表,而是一个生成器对象,通过生成器可以获取数据,它不占用额外的空间存储数据,每次需要数据的时候就通过生成器取数据,这就需要花费时间
f = (x ** x for x in range(1, 10)) # 生成一个1的1次方到9的9次方的列表
查看对象占用内存空间的函数:sys.getsizeof()
sys.getsizeof(list3)
sys.getsizeof(f)
-
定义多维列表
易错写法:此方法不正确,因为元素的索引不正确
scores = [[0] * len(subjects)] * len(names)
正确写法:
scores = [[0 for _ in range(3)] for _ in range(5)]
scores = [[0] * len(subjects) for _ in range(len(names))]
陷阱:
如果要创建一个list5,这个列表和list4完全相同,易错写成下面这种方式,
list4 = [x for x in range(1, 9)]
list5 = list4
上面这种方式,表面上是创建了一个新的列表(一个列表就是一个对象,并且所有的一切都是对象),实际上内存中只存在一个列表对象,要理解这个问题,我们先了解下面的知识点:
cpu(内存)分为三个部分:栈(stack),堆(heap),静态区(数据段、只读数据段、代码段)。栈用于存放变量,堆用于存放所有对象,变量是记录对象在堆上的地址,假如创建一个变量a = 100,实际是在堆上创建一个对象100,变量a记录对象100在堆上的位置,并且变量a存放在栈上,所以变量实际是对对象的引用。
知道了这个原理,就很容易理解上面的问题,list5 = list4 实际是把对象在栈上的地址赋给了list5,堆上的列表对象只有一个,栈上面有两个变量引用了这个列表对象。
查看对象的身份(地址):内置函数 - id()
# 查看对象的身份
a = 1000
b = 1000
id(a)
id(b)
查看对象被引用的次数:此处list4被引用的次数是3,一次引用是list4 ,一次引用是list5, 还有一次是执行下面这句代码时被引用
sys.getrefcount(list4)
正确的写法如下:表示生成一个和list4相同的列表,把此列表(对象)在堆中的地址存在变量list5中,此时堆上面有两个列表对象。
list5 = list4[:]
-
list可进行的操作
访问某个元素:取出列表第一个元素
f[0]
在列表末尾追加值:
f.append() # 只能追加一个值
f = f + [600, 900] # 可以是多个值
在列表某个位置插入值:在f[2]插入100,如果定义的位置超出了索引范围,如果小于0,则直接在最前面插入;如果大于最大索引,则直接在最后插入。
f.insert(2,100)
删除某个元素:若这个元素不在列表内,程序会报错,所以要先判断这个元素是否存在于列表中
if 5000 in f:
f.remove(5000)
删除某个位置的元素:删除第3个元素
del f[2]
删除元素:pop默认删除最后一个元素,也可以传入参数 - 索引 删除某个位置的元素
f.pop()
查找某个元素的位置:查找一个元素,若此元素存在,则返回这个元素的位置即索引;若此元素不存在,香醋会报错
f.index(100) # 在整个列表中查找元素100
f.index(100, 1, 3) # 在第1位到第3位之间查找元素100
翻转列表:可根据是否想改变元列表的顺序选择方法或函数,方法是直接把翻转后的列表赋值给原列表,函数则是生成一个新的翻转后的列表,原列表不变。
f.reverse() # 方法
f1 = reversed(f) # 函数,f不变
元素排序:Python内置的排序方法默认都是排升序(从小到大),若想排降序,可使用reverse参数,当他的值为True时翻转,为False时不翻转。key可以指定排序规则,如下例是让其按照单词的长度进行排序
f = ['red', 'grade', 'internationlization', 'zoo', 'classmate']
f.sort(key=str_len, reverse=True) # 方法
def str_len(s):
return len(s)
# len是内置求长度的函数,官方不建议使用
# 自己定义一个求列表长度的函数str_len(),return一个len()
f1 = sorted(f, key=str_len, reverse=True) # 函数
遍历列表:只返回元素;返回索引和对应的元素:枚举法enumerate
for val in f:
print(val)
for index,val ball in enumerate(f): # 枚举法
print(index, val)
-
实例
生成fibonacci序列:[1, 1, 2, 3, 5, 8, 13, 21, ...]
def fibonacci():
current_fibonacci = [1, 1]
for _ in range(18):
current_fibonacci.append(current_fibonacci[-1] + current_fibonacci[-2])
return current_fibonacci
设计一个函数,计算传入的成绩列表的平均分,要求去掉一个最高分和一个最低分
def mean(list_grade):
grade_max = grade_min = list_grade[0]
for val in list_grade:
if val > grade_max:
grade_max = val
if val < grade_min:
grade_min = val
list_grade.remove(grade_max)
list_grade.remove(grade_min)
total = 0
for new_val in list_grade:
total += new_val
return total / len(list_grade)
输入已有学生的成绩,找最高分和最低分,并知道对应的同学名字
def seclct_name_grade():
names = ['零零', '一一', '二二', '三三', '四四', '五五', '六六', '七七']
grades = []
for val in names:
grade = int(input('输入%s的成绩:' % val))
grades.append(grade)
pos_max = grades.index(max(grades))
pos_min = grades.index(min(grades))
print('最高分学生:%s | 成绩:%d' % (names[pos_max], grades[pos_max]))
print('最低分学生:%s | 成绩:%d' % (names[pos_min], grades[pos_min]))
从传入的列表中找出第二大的元素,只能用一次循环
def second(your_list):
"""
找出列表中第二大的元素
:param your_list: 一个全数字的列表
:return: 列表中第二大的元素
"""
your_max = your_second = your_list[0]
for num in range(1, len(your_list)):
if your_list[num] > your_max:
your_second = your_max
your_max = your_list[num]
elif your_second < your_list[num] < your_max:
your_second = your_list[num]
return your_second
机选n注双色球中奖号码
6个红色球(1 ~ 33)和1个蓝色球(1 ~ 16)
彩票号码的顺序符合规则:红色球号码(不重复,且从小到大) + 蓝色球号码双色球
def random_select():
"""
生成一注双色球号码
:return: 一注双色球号码
"""
# 生成一个1-33的列表 也看用下面这张方式red_balls = [x for x in randint(1, 33)]
# randrange(n)默认从0开始取,取到(n - 1)
red_balls = list(randrange(1, 34))
all_balls = []
for _ in range(6):
index = randrange(len(red_balls))
all_balls.append(red_balls[index])
del red_balls[index]
all_balls.sort()
blue_ball = randint(1, 16)
all_balls.append(blue_ball)
return all_balls
def display(balls):
"""
打印双色球彩票号码
:param balls: 双色球彩票号码的列表
:return: 打印彩票号码的样式
"""
for index, ball in enumerate(balls):
if index == len(balls) - 1: # 遍历到列表最后一位时,打印1个竖线
print('|', end=' ')
print('%02d' % ball, end=' ') # %02d是一个整数类型的占位符,2表示这个整数的位数,若当前整数不满2位,则在前面填充数字0
print()
def lottery_amount():
"""
生成n注彩票
:return: 打印出n注彩票的号码
"""
n = int(input('买几注双色球彩票:'))
for _ in range(n):
display(random_select())
生成一个列表,记录每个同学的多门课程成绩
def main():
names = ['关羽', '张飞', '赵云', '马超', '貂蝉']
subjects = ['语文', '数学', 'Python']
scores = [[0 for _ in range(3)] for _ in range(5)]
for row, name in enumerate(names):
print('输入%s的成绩' % name)
for col, subject in enumerate(subjects):
score = input('%s:' % subject)
scores[row][col] = score
print(scores)
30个人,15个基督徒,15个非基督徒,30个人围成圈,从1个位置开始报数,数到9的人不能存活,最后只能存活15个人,且都是基督教人,求这30个人的站位
def people_pos():
people = [True] * 30 # 生成一个列表,代表活着的30个人
counter = 0 # 记录死去的人的数目
index = 0 # 人在列表中的位置(下标)
number = 0 # 记录报的数
while counter < 15:
if people[index]: # 如果这个人活着
number += 1 # 报数加1
if number == 9: # 如果报数到9
people[index] = False # 把报数9的这个人设置为死亡状态
number = 0 # 接着往下数,但要重新开始报数
index += 1 # 每执行一次循环,下标往后移1,判断下一个人是否活着
index %= 30 # 当下标移动到到29后,全部人已数过一遍,所以在index=30时,应该又从第一个人开始数,使index的值为0
# 设计一个函数传入年,月,日,返回这一天是这一年的第几天
def is_leap_year(year):
return year % 4 == 0 and year % 100 != 0 or year % 400 == 0
def which_day(year, month, date):
"""
传入一个年月日,计算这一天是这一年的第几天
:param year: 年
:param month: 月
:param date: 日
:return: 这一天是这一年的第几天
"""
days_of_month = [
[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
[31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
][is_leap_year(year)]
# [is_leap(year)]代表下标,是一个布尔值
# 若[is_leap(year)]为真,则返回一个1,days_of_month = days_of_month[1]
# 若[is_leap(year)]为假,则返回一个0,days_of_month = days_of_month[0]
total = 0
for mon in range(month - 1): # 若month = 1,则month - 1 = 0,循环不会执行
total += days_of_month[mon]
return total + date
传入n,生成n行的杨辉三角
# 1
# 1 1
# 1 2 1
# 1 3 3 1
# 1 4 6 4 1
def pascal_triangle(n):
triangle = []
t = [1]
for row in range(1, n + 1):
new_t = [1] * row
for col in range(1, row):
t.append(0)
new_t[col] = t[col] + t[col - 1]
t = new_t[:]
triangle.append(new_t)
return triangle
def display_triangle(x):
for row in x:
for col in row:
print(col, end=' ')
print()
设计一个函数,生成蛇形数组
# 1 2 3 4 5
# 16 17 18 19 6
# 15 24 25 20 7
# 14 23 22 21 8
# 13 12 11 10 9
def ring_figure(n):
r = [[1] * n for _ in range(1, 6)] # 生成1个n行n列的列表
x = n # 计数
time = 1 # 循环次数
start_num = 1 # 循环开始时的数字
row_right = 0 # 行的索引
row_left = n - 1 # 行的索引
col_down = n - 1 # 列的索引
col_up = 0 # 列的索引
running = True
while running :
if (time - 1) % 4 == 0: # 向右加数字
num1 = row_right # 此行的列下标
for num2 in range(start_num, x + 1):
r[row_right][num1] = num2
num1 += 1
row_right += 1
elif (time - 2) % 4 == 0: # 向下加数字
num3 = row_right # 此列的行坐标
for num4 in range(start_num, x + 1):
r[num3][col_down] = num4
num3 += 1
col_down -= 1
elif (time - 3) % 4 == 0: # 向左加数字
num5 = col_down # 此行的列坐标
for num6 in range(start_num, x + 1):
r[row_left][num5] = num6
num5 -= 1
row_left -= 1
elif (time - 4) % 4 == 0: # 向上加数字
num7 = row_left # 此列的行坐标
for num8 in range(start_num, x + 1):
r[num7][col_up] = num8
num7 -= 1
col_up += 1
time += 1
start_num = x + 1
x += n - time // 2
if n - time // 2 == 0:
running = False
return r
def display_ring(x):
for row in x:
for col in row:
str_col = str(col)
print(str_col.center(6, ' '), end=' ')
print()
tuple
元组也是一种有序集合,他和列表非常相似,但和列表最大的不同在于:元组是不可变的,即元组一旦初始化就不能修改,所以没有插入、删除等操作。
元组在时间和空间上都优于列表,所以能使用元组就不使用列表。
-
定义tuple
元组是用()表示
t1 = (1, 3, 5,[2, 5, 7])
注意:元组中的元素一旦被初始化就不能修改,但元组中的列表内的值可以修改。
-
陷阱
定义一个空元组,可直接写做:
t = ()
定义一个只有1个元素的元组
易错写格式:
t = (1)
t =(1)定义的不是tuple,是1这个数!这是因为括号()既可以表示tuple,又可以表示数学公式中的小括号,这就产生了歧义,因此,Python规定,这种情况下,按小括号进行计算,计算结果自然是1。
正确格式:
t = (1,)
Python在显示只有1个元素的tuple时,也会加一个逗号,以免你误解成数学计算意义上的括号。
set
set是一个没有序列的集合,并且会自动过滤相同的元素,所以集合中的元素都是唯一的。
-
定义set
集合用{}表示
set1 = {1, 1, 2, 3, 4, 5, 5}
set2 = {1, 3, 5, 9, 10}
-
set可进行的操作
在集合内加入元素:
set1.add(6)
交集:取set1 和 set2相同的部分
set3 = set1 & set2
set3 = set1.intersection(set2)
并集:取set1 和 set2 所有元素
set3 = set1 | set2
set3 = set1.union(set2)
差集:set1中去除set1和set2相同的元素
set3 = set1 - set2
set3 = set1.difference(set2)
对称差:set1去掉set1 和 set2 相同的元素,set2 去掉set1 和 set2 相同的元素
set3 = set1 ^ set2
set3 = set1.symmetric_difference(set2)
遍历
for val in set2:
print(val)
随机删除,计算机内部有一套删除机制
set2.pop()
删除某个元素:若元素不存在,程序会报错,所以先判断元素是否在集合内
if 2 in set2:
set2.remove(2)
判断set2 是否是 set1 的子集
print(set2 <= set1)
print(set2.issubset(set1))
判断set1 是否是 set2 的超集
print(set1 >= set2)
print(set1.issuperset(set2))
列表变集合
list1 = [1, 2, 3, 1, 2, 4]
set1 = set(list1)
dict
字典没有索引,使用键 - 值(key - value)方式存储,一个键对应一个值,所以查找速度极快,但占用空间较大。
-
定义dict
字典用{}表示,一个key对应一个value
dict1 = {'name': '李民', 'age': '19', 'gender': True}
-
dict的操作
用key找value
dict1['name']
修改值:通过key找到value,进行修改。由于一个key只能对应一个value,所以多次对一个key放入value,后面的值会把前面的值覆盖掉。如果key不存在,程序会报错,使用要先判断key是否在字典中。
if name in diat1:
dict1['name'] = 李安
更新:增加新的key和对应的value
dict1.update(height=170, fav=['吃', '喝']) # height 和fav为key,后面是对应的值
删除字典:把dict1 和引用断开了
del dict1
删除键和对应的值
del dict1['name']
dict1.pop('name')
删除最后一对键值
dict1.popitem()
给键设置默认值
dict1.setdefault('age', '20')
更新(给字典增加新的键值对)
dict2 = {'name': 'lvping'}
dict1.update(dict2)
dict1.update({''})
遍历:
1.遍历键:两种方式
for x in dict1:
print(x, '--->', dict1[x])
for x in dict1.keys():
print(x, '--->', dict1[x])
2.遍历值
用values()函数,可直接遍历字典的中值
for y in dict1.values():
print(y)
实例:把字典的键和值颠倒
def main():
d1 = {'firstname': 'Lv', 'lastname': 'Ping', 'tel': 13322222222}
d2 = {}
for key in d1:
new_key = str(d1[key])
new_value = key
d2.update({new_key: new_value})
d1 = d2
print(d1)
if __name__ == '__main__':
main()