http://abcxueyuan.cloud.baidu.com/#/read_resource?docId=doc-kcgyaq14z8wqwbn&resourceId=291&courseId=15204&type=%E5%85%8D%E8%B4%B9%E8%AF%BE%E7%A8%8B
字符串
字符串类型
字符串是最常用的数据类型之一,它用来表示一串不可变的字符。 字符串可以使用双引号或者单引号将字符包含起来,例如:
[1]:
“this is a book”
[1]:
‘这是一本书’
[2]:
‘这是一本书’
[2]:
‘这是一本书’
如果字符串中本来就含有单引号或者双引号,可以通过下面的方法来处理:
- 如果字符串中包含单引号,则使用双引号来包裹这个字符串,反之,如果字符串中包含双引号,则使用单引号来包裹这个字符串,例如:
[3]:
“She’s a student”
[3]:
“She’s a student”
[4]:
‘She said:”I am a student.”‘
[4]:
‘She said:”I am a student.”‘
- 如果字符串中即有单引号又有双引号,则可以对字符串内的单双引号进行转义,即在字符串内的单双引号前面加上\,例如:
[5]:
‘She\’s a student’
[5]:
“She’s a student”
中文的全角单双引号不受影响,即中文单双引号会被当做普通字符。 对于内容复杂的字符串,也可以使用””””””或者’’’’’’来包裹字符串,此时无论里面有单引号还是双引号,均会被原封不动地正确处理。
[7]:
s = “””
Whether you’re new to programming or an experienced developer,
it’s easy to learn and use Python.
“””
print(s)
Whether you’re new to programming or an experienced developer,
it’s easy to learn and use Python.
使用%占位符格式化字符串
有时候,我们可能需要在字符串中加入一些不确定的内容,例如,根据用户的输入,输出语句问候语:
[8]:
name = input(“输入您的名字:”)
print(“您好,” + name)
输入您的名字:张三
您好,张三
这种方式可以实现我们的目的,但它在可读性和性能上都不够优化。所以在Python中陆续提供了三种格式化字符串的方式。我们先来看第一种:使用占位符%。 如果将上面的代码改成使用%占位符,它可以修改成如下:
[9]:
name = input(“输入您的名字:”)
print(“您好,%s” % name)
输入您的名字:张三
您好,张三
这种方式的好处是,%占位符可以自动将非字符串类型的数据转换成字符串,并和字符串其他部分相连接,形成新的字符串。 它的标准格式是: %[(name)][flags][width].[precision]typecode
[12]:
name = “张三”
salary = 18600.78
age = 30
print(“%s,今年%d岁,这个月薪资是:%.2f” % (name, age, salary))
张三,今年30岁,这个月薪资是:18600.78
[13]:
print(‘%5d-%02d’ % (300, 1)) # 指定显示长度,以及填补不足的字符
300-01
[14]:
print(‘%.2f’ % 3.1415926) # 指定浮点数精度
3.14
[15]:
print(‘%-10s’ % (‘hello’)) # 指定对齐方式和长度
hello
除了f、s、d外的其他格式字符,请见下面例子:
[16]:
print(“guess a char %c” %(‘g’)) # 字符
print(“229 转换成十六进制是: %x”%(229))
print(“229 转换成八进制 %o” % (229))
print(“10086 转换成自然对数表示%e”%(10086))
print(“-1000 %u”%(-1000))
print(“二进制10010的十进制值是:%d”%(0b10010))
print(0b10010) #二进制表示
print(0x10086) #十六进制表示
print(0o100) #二进制表示
guess a char g
229 转换成十六进制是: e5
229 转换成八进制 345
10086 转换成自然对数表示1.008600e+04
-1000 -1000
二进制10010的十进制值是:18
18
65670
64
指定name的方式:
[22]:
print(‘%(country)s有%(number)03d 个民族。’ % \
{“country”: “中国”, “number”: 56})
中国有056 个民族。
这种格式化数据慢慢被抛弃了,因为它的占位符和值之间必须一一对应,在占位符比较多的时候,比较容易出错。
使用format()函数格式化字符串
Python 2.6之后引入了str.format()函数,对格式化字符串处理更强大、更灵活:
[23]:
name = “李雷”
age = 16
print(“{}今年{}岁”.format(name, age))
李雷今年16岁
着这种方式下,使用{}作为占位符,但它的好处在于可以给它指定顺序,例如:
[24]:
name = “李雷”
age = 16
print(“{1}今年{0}岁”.format(age, name))
李雷今年16岁
还可以加入变量:
[25]:
name = “李雷”
age = 16
print(“{n},您好,您今年{a}岁。”.format(n=name, a=age))
李雷,您好,您今年16岁。
考虑下面这种情况:A喜欢B,可B不喜欢A 如果A、B待定,用前面的格式化方式定义如下:”%s喜欢%s,可%s不喜欢%s” %(“A”,”B”,”B”,”A”) 这种方式的问题在于:
- 都用%s来指定,看不出A、B的区别
- A、B其实各重复了一次,如果重复多次,需要重复写更多次。 如果用format()函数,可以写成:
[28]:
print(“{0}喜欢{1},可{1}不喜欢{0}”.format(“李雷”,”韩梅梅”))
李雷喜欢韩梅梅,可韩梅梅不喜欢李雷
当然,在format()中也可以使用类似%一样的数据类型等设置:
[29]:
name = “李雷”
age = 16
print(“{:s},您好,您今年{:d}岁。”.format(name, age))
print(“{0:s},您好,您今年{1:d}岁。”.format(name, age))
print(“{n:s},您好,您今年{a:d}岁。”.format(n=name, a=age))
李雷,您好,您今年16岁。
李雷,您好,您今年16岁。
李雷,您好,您今年16岁。
指定长度和精度:
[30]:
name = “李雷”
salary = 10086.19
print(“{:10s},您的月薪是:{:.1f}”.format(name, salary))
print(“{0:10s},您的月薪是:{1:.1f}”.format(name, salary))
print(“{n:10s},您的月薪是:{s:.1f}”.format(n=name, s=salary))
李雷 ,您的月薪是:10086.2
李雷 ,您的月薪是:10086.2
李雷 ,您的月薪是:10086.2
另外,在指定了长度之后,如果对应的值不足,可以指定补足的字符(默认是空格,例如上面张三后面的空格),此时必须配合对齐方式来使用:
- “<”:左对齐
- “^”:居中对齐
- “>”:右对齐
[31]:
name = “李雷”
salary = 10086.19
print(“{n:^10s},您的月薪是:{s:.1f}”.format(n=name, s=salary))
*李雷,您的月薪是:10086.2
使用f-string来格式化字符串
format()方法相比较%来说已经有明显的改进,但在某些复杂情况下,还是显得不够灵活。例如:
[32]:
name = “张三”
age = 34
profession = “讲师”
subject = “计算机”
city = “北京”
print((“您好, {name}。您今年 {age}岁。” +
“您是一名{profession}。 您在{city}教{subject}。”)
.format(name=name, age=age,
profession=profession, city=city, subject=subject))
您好, 张三。您今年 34岁。您是一名讲师。 您在北京教计算机。
可以看到,一旦参数比较多,在使用format()的时候,需要做比较多的无用功。其实如果能直接在{}中,和变量直接一一对应,那就方便很多了。 f-string,就是Phont 3.6中为了实现这个目的而设计的格式化字符串方式。 上面的这个实验,可以使用f-string改成:
[33]:
name = “张三”
age = 34
profession = “讲师”
subject = “计算机”
city = “北京”
print(f”您好, {name}。您今年 {age}岁。\
您是一名{profession}。 您在{city}教{subject}。”)
您好, 张三。您今年 34岁。您是一名讲师。 您在北京教计算机。
因为f-string的{}中的内容,会在运行时进行运算,因此在{}中也可以直接调用函数、使用表达式,例如:
[34]:
birthyear = 1999
print(f”您的年龄大约为:{2020 - birth_year}”)
您的年龄大约为:21
对于多行文字,为了让代码更美观易读,应该写成如下方式:
[35]:
print(f”您好,{name}。您今年{age}岁。”
f”您是一名{profession}。您在{city}教{subject}。”)
您好,张三。您今年34岁。您是一名讲师。您在北京教计算机。
当然,在f-string中也可以使用上面的各种限制:
[36]:
val = 12.3
print(f’{val:.2f}’)
print(f’{val:.5f}’)
12.30
12.30000
再如:
[37]:
for x in range(1, 11):
print(f’{x:02} {x*x:3} {x*x*x:4}’)
01 1 1
02 4 8
03 9 27
04 16 64
05 25 125
06 36 216
07 49 343
08 64 512
09 81 729
10 100 1000
指定对齐方式:
[38]:
s1 = ‘a’
s2 = ‘ab’
s3 = ‘abc’
s4 = ‘abcd’
print(f’{s1:>4}’)
print(f’{s2:>4}’)
print(f’{s3:>4}’)
print(f’{s4:>4}’)
a
ab
abc
abcd
不同进制、不同表示方式的数字:
[39]:
# 数字符号
a = 300
# hexadecimal,十六进制
print(f”{a:x}”)
# octal,八进制
print(f”{a:o}”)
# binary,二进制
print(f”{a:b}”)
# scientific,科学计数_
print(f”{a:e}”)
12c
454
100101100
3.000000e+02
字符串操作
如果要从字符串中获得其中的一段子字符串,可以通过str[start:end]的方法来获得。其中start为开始索引,end为结束索引,但end对应索引的字符不包含在内。如果只取单个字符,则只需要指定start参数就可以了。
[40]:
s = “hello world”
print(s[0:2])
print(s[:2])
print(s[4:])
print(s[-1:])
print(s[:-1])
print(s[4])
he
he
o world
d
hello worl
o
我们经常需要对字符串进行操作,所以Python提供了很多字符串操作的函数供我们使用。
- capitalize():字符串首字母大写
- title():将字符串中各个单词的首字母大写
- lstrip()、rstrip()、strip():分别用于去除字符串左边、右边和左右两边的空格
- 需要注意的是,上面这些方法,都不会改变原有字符串内容,而是新生成字符串
- startswith(prefix, start, end):该字符串是否以某个字符串开始
- endswith(suffix, start, end):该字符串是否已某个字符串结尾
- find(s, start, end):从字符串中从左到右寻找是否包含字符串s,返回找到的第一个位置。如果没找到,返回-1
- rfind(s, start, end):和find()类似,只不过它从右到左寻找
- index(s, start, end):和find()类似,但如果没找到将会返回错误
- rindex(s, start, end):和index()类似,只不过它从右到左寻找
- isalnum():如果字符串中至少有一个字符,且字符串由数字和字母组成,则为true。
- isalpha():如果字符串中至少有一个字符,且字符串由字母组成,则为true
- isdigit():是否为数字(整数),小数点不算,只支持阿拉伯数字
- isnumeric():是否为数字。支持本地语言下的数字,例如中文“一千三百”、“壹万捌仟”等
- replace(s1, s2):将字符串中的s1替换成s2
[41]:
s = “tom jerry mike mary”
print(s.find(“jerry”))
print(s.upper())
s = “tom jerry mike mary”
s1 = s.replace(“mary”,”mario”)
print(s1)
4
TOM JERRY MIKE MARY
tom jerry mike mario
下面我们看一个综合案例。 指定字符串中,将字符串中和第一个字母一样的字母(除第一个字符本身外), 都替换成另一个字符“@”,例如:little,替换后成为litt@e, 即将little中所有的l(第一个字母是l)都替换成@(除了第一个字母本身), 下面是一种实现思路:
[42]:
str1 = “little”
char = str1[0]
new_str = str1.replace(char, ‘@’)
new_str = char + new_str[1:]
print(new_str)
litt@e
list和tuple
使用列表list或者元组tuple,可以存放一系列的数据,例如,将班级所有同学的名字放在一起: names = [“张三”, “李四”, “王五”]
list
list是一种有序的、可变的数据集合,可变的意思就是可以随时往里添加或者删除元素。 可以通过索引从中取出元素,例如names[1]将取出第二个数据(索引从0开始)。
- 如果索引超出范围(例如索引大于等于列表个数),将会报错
- 索引可以是负数,负数表示从后往前计数取数据,最后一个元素的索引此时为-1
[43]:
names = [“张三”,”李雷”,”韩梅梅”]
print(names)
print(names[1])
print(names[-1])
[‘张三’, ‘李雷’, ‘韩梅梅’]
李雷
韩梅梅
列表中的元素,其数据类型不一定要一样。甚至可以使用列表数据作为另一个列表的元素。如: names = [“张三”,”李四”, [“Leonardo”,”Dicaprio”], “王五”],其中,第三个元素(索引为2)为另一个列表 此时,names[2]取出来的值是列表[“Leonardo”,“Dicaprio”],要取Leonardo这个值,则需要在这个列表[“Leonardo”, “Dicaprio”]上使用索引0去获取,因此,可以通过names[2][0]取得
[44]:
names = [“张三”,”李四”, [“Leonardo”,”Dicaprio”], “王五”]
print(names[2][0])
Leonardo
如果要从列表中取出一定范围内的元素,则可以使用list[start:end]的方式来获取,例如:names[1:3]取出从索引1开始到索引3结束(不包含索引3)的2个元素。
- start如果省略,表示从0开始
- end如果省略,表示到列表最后一个元素结束
[45]:
names = [“张三”,”李四”, [“Leonardo”,”Dicaprio”], “王五”]
print(names)
# 取出一定范围内的元素
print(names[1:3]) # 取出索引从1开始到3(不包含3)结束的元素
[‘张三’, ‘李四’, [‘Leonardo’, ‘Dicaprio’], ‘王五’]
[‘李四’, [‘Leonardo’, ‘Dicaprio’]]
如果要创建一系列数字为内容的列表,可以结合list()函数和range()函数来创建,例如,创建包含数字0-99的列表:
[47]:
print(list(range(100)))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
range(0, 100)
range()的函数原型:
- range(stop) :0开始计数,计数到stop结束,但不包括stop,例如:range(10),生成的数字范围是0-9
- range(start, stop[, step]):计数从 start 开始,到stop结束(不包括stop),step是步长,即每次变化的范围,默认为1,即每次加1
- start/stop/step均可以为任意整数
- “start < stop”,才能生成包含元素的range,如果stop< start,则为空。
[51]:
a = range(1,10)
print(list(a))
b = range(-10) # 这里会生成空的range范围,它相当于0~-10
print(list(b))
b = range(0, -10) #还是为空
print(list(b))
b = range(-10, 0)
print(list(b)) # 不为空
c = range(0,100,5)
print(list(c))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[]
[]
[-10, -9, -8, -7, -6, -5, -4, -3, -2, -1]
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
list操作函数
- append(element):往列表最后附加一个元素
- insert(index, element):往列表指定索引位置插入一个元素
- 可以直接给指定索引元素赋值,用新值替代旧值:names[idx]= value
- pop()将最后一个元素从列表中取出来,并从列表中删除该元素
- 如果要删除列表中的一个索引对应的元素,可以使用del list[idx]的方式
- extend(seq):在原来的列表后追加一个系列
- remove(obj):从列表中删除第一个匹配obj的元素
- clear():清空整个列表
- count(obj):计算元素obj在列表中出现次数
- sort(key=…, reverse=…):给list排序,可以指定用于排序的key。reverse用于指定是否反序。
[53]:
c = range(0,100,5)
d = list(c)
d.extend(range(0, -100, -5))
print(d)
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 0, -5, -10, -15, -20, -25, -30, -35, -40, -45, -50, -55, -60, -65, -70, -75, -80, -85, -90, -95]
[65]:
casts = [“Robert De Niro”, “Al Pacino”, \
“Joe Pesci”, “Harvey Keitel”, “Bobby Cannavale”]
print(“未排序:”)
print(casts)
print(“正序:”)
casts.sort() #正序
print(casts)
print(“反序:”)
casts.sort(reverse=True)
print(casts)
未排序:
[‘Robert De Niro’, ‘Al Pacino’, ‘Joe Pesci’, ‘Harvey Keitel’, ‘Bobby Cannavale’]
正序:
[‘Al Pacino’, ‘Bobby Cannavale’, ‘Harvey Keitel’, ‘Joe Pesci’, ‘Robert De Niro’]
反序:
[‘Robert De Niro’, ‘Joe Pesci’, ‘Harvey Keitel’, ‘Bobby Cannavale’, ‘Al Pacino’]
下面我们来看一个更复杂的列表: theirishman = [[“Robert”, “De Niro”], [“Al”, “Pacino”], \ [“Joe”, “Pesci”], [“Harvey”, “Keitel”], [“Bobby”, “Cannavale”]] 假设我们现在要给它进行排序,那么应该是按照first name还是last name来排序呢? 此时就需要用到sort()函数中的key参数了。通过key可以给它指定一个函数,这个函数来限制应该按照first name还是last name来排序:
[66]:
the_irishman = [[“Robert”, “De Niro”], [“Al”, “Pacino”], \
[“Joe”, “Pesci”], [“Harvey”, “Keitel”], [“Bobby”, “Cannavale”]]
print(“未排序”)
print(the_irishman)
def lastname(ele):
return ele[1] # 取出last name_
print(“按姓(last name)排序”)
the_irishman.sort(key=lastname)
print(the_irishman)
未排序
[[‘Robert’, ‘De Niro’], [‘Al’, ‘Pacino’], [‘Joe’, ‘Pesci’], [‘Harvey’, ‘Keitel’], [‘Bobby’, ‘Cannavale’]]
按姓(last name)排序
[[‘Bobby’, ‘Cannavale’], [‘Robert’, ‘De Niro’], [‘Harvey’, ‘Keitel’], [‘Al’, ‘Pacino’], [‘Joe’, ‘Pesci’]]
tuple
tuple和列表类似,它们的区别在于tuple是不可变的,即如果元组初始化了,则不能改变,tuple没有pop()/insert()这些方法。 需要注意的是,这里的不可变,指的是不能直接将tuple元素改变成另一个元素,但如果tuple的元素是一个可变对象,例如list,那么,list里面的内容是可以改变的,但不能用另一个list去替换tuple中既有的list。
[55]:
tnames = (“张三”,”李四”,”王五”)
print(tnames)
tnames = (“张三”,”李四”, [“Leonardo”,”Dicaprio”], “王五”)
# tnames[2] = [“Brad”,”Peter”] # 这是不允许的
tnames[2][0] = “Jackson” # 这是可以的
print(tnames)
(‘张三’, ‘李四’, ‘王五’)
(‘张三’, ‘李四’, [‘Jackson’, ‘Dicaprio’], ‘王五’)
元组还有一个需要特别注意的地方是只有一个元素的元组数据的定义。因为()还是表达式中使用的符号(用来改变操作符顺序),因此如果只有一个元素,定义成 names = (“张三”),此时()会被当做表达式符号,这里就会被忽略掉,因此names的值此时为字符串”张三”,而不是元组类型。为避免这种情况,可以这样定义单个元素的元组数据:names = (“张三”,)
[57]:
#只有一个元素的tuple
age = (20,)
print(age)
names = (“张三”) # 此时会被当做一个字符串,而不是一个元组
print(names)
n = (“张三”,) # 此时才会被当做一个元组
print(n)
print(len(n)) # 长度为1
(20,)
张三
(‘张三’,)
1
另外还可以使用下面的方法创建元组:
[59]:
# 另一种创建tuple的方法
grades = 1, 2, 3, 4
print(grades)
(1, 2, 3, 4)
列表和元组均可以乘以一个整数n,表示将原来列表或者元组中的数据复制n份生成新列表或者元组:
[60]:
print(3 * grades)
(1, 2, 3, 4)
(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4)
列表和列表之间、元组和元组之间,可以使用“+”将两个列表或者元组中的数据合并成新的列表或者元组
[63]:
grades = 1, 2, 3, 4
names = (“张三”,”李四”,”王五”)
print(names + grades) # 合并元组
(‘张三’, ‘李四’, ‘王五’, 1, 2, 3, 4)
注意,tuple和list是不能合并的。 如果想逐个取出列表或者元组中的元素,可以通过for…in…的方式逐个取出元素:
[64]:
for i in grades:
print(i)
1
2
3
4
字典类型
字典(dict)是用于保存键-值(key-value)对的可变容器数据。 字典的每个键值(key-value)对用冒号(:)分割,每个键值对之间用逗号(,)分割,整个字典包括在花括号({})中 ,格式如下所示:
- d = {key1 : value1, key2 : value2 } 注意,字典中的key必须唯一,即不能有两对key一样的元素。 可以通过d[key]的方式,获得对应key的value。如果不存在对应的key,则会报错。
[68]:
teams = {“Phoenix”: “Suns”, “Atlanta”: “Hawks”, “Boston”: “Celtics”,
“Chicago”: “Bulls”, “Denver”: “Nuggets”, “Detroit”: “Pistons”,
“Los Angels”: “Clippers”}
print(teams)
print(teams[“Phoenix”]) #通过key访问值
{‘Phoenix’: ‘Suns’, ‘Atlanta’: ‘Hawks’, ‘Boston’: ‘Celtics’, ‘Chicago’: ‘Bulls’, ‘Denver’: ‘Nuggets’, ‘Detroit’: ‘Pistons’, ‘Los Angels’: ‘Clippers’}
Suns
- 给字典增加数据,可以通过
- d[new_key] = new_value
- 修改某个key对应的值 -d[key] = new_value
- 删除某个key对应的元素
- del d[key],将会删除key对应的键值对,不仅仅是删除值
- del d,将会删除整个字典数据
[69]:
teams[‘Los Angels’] = “Lakers” # 将洛杉矶对应的球队改成了湖人队
teams[‘Orando’] = “Magics”
print(teams)
{‘Phoenix’: ‘Suns’, ‘Atlanta’: ‘Hawks’, ‘Boston’: ‘Celtics’, ‘Chicago’: ‘Bulls’, ‘Denver’: ‘Nuggets’, ‘Detroit’: ‘Pistons’, ‘Los Angels’: ‘Lakers’, ‘Orando’: ‘Magics’}
为了避免key的不唯一,要求key只能使用不变的数据做key,例如:数字、字符串、元组。list因为是可变数据,所以不能当做key。
字典类型操作方法
- items():以列表返回可遍历的(键, 值) 元组数组
- keys():返回一个包含所有键的可迭代对象,可以使用 list() 来转换为列表
- values():返回一个包含所有值的可迭代对象,可以使用 list() 来转换为列表
- pop(key[,default]):取出对应key的值,如果不存在,则使用default值
- popitem():取出字典中最后一个key-value对
- get(key[,default]):取出对应key的值,如果不存在这个key,则使用default值
[74]:
teams = {“Phoenix”: “Suns”, “Atlanta”: “Hawks”, “Boston”: “Celtics”,
“Chicago”: “Bulls”, “Denver”: “Nuggets”, “Detroit”: “Pistons”,
“Los Angels”: “Clippers”}
print(teams.keys())
print(teams.values())
print(teams.items())
# 逐个取出字典中的元素
for key in teams:
print(teams[key])
print()
print(teams.pop(“Denver”)) #取出丹佛对应的值
print(teams) #此时已经没有丹佛掘金队了
print(teams.popitem()) #取出最后一个队,即洛杉矶
print(teams) # 没有洛杉矶快船队了
print(teams[“Phoenix”]) #通过key访问值
dict_keys([‘Phoenix’, ‘Atlanta’, ‘Boston’, ‘Chicago’, ‘Denver’, ‘Detroit’, ‘Los Angels’])
dict_values([‘Suns’, ‘Hawks’, ‘Celtics’, ‘Bulls’, ‘Nuggets’, ‘Pistons’, ‘Clippers’])
dict_items([(‘Phoenix’, ‘Suns’), (‘Atlanta’, ‘Hawks’), (‘Boston’, ‘Celtics’), (‘Chicago’, ‘Bulls’), (‘Denver’, ‘Nuggets’), (‘Detroit’, ‘Pistons’), (‘Los Angels’, ‘Clippers’)])
Suns
Hawks
Celtics
Bulls
Nuggets
Pistons
Clippers
Nuggets
{‘Phoenix’: ‘Suns’, ‘Atlanta’: ‘Hawks’, ‘Boston’: ‘Celtics’, ‘Chicago’: ‘Bulls’, ‘Detroit’: ‘Pistons’, ‘Los Angels’: ‘Clippers’}
(‘Los Angels’, ‘Clippers’)
{‘Phoenix’: ‘Suns’, ‘Atlanta’: ‘Hawks’, ‘Boston’: ‘Celtics’, ‘Chicago’: ‘Bulls’, ‘Detroit’: ‘Pistons’}
Suns
集合类型
集合(set)是一个无序的不重复元素序列。 可以使用set()或者{}来创建一个集合:
- 如果使用{}创建集合,要注意和字典数据类型的区别——字典数据里是key-value对,而这里是单个的数据
- 如果创建空集合,不可以使用{},因为系统会首先将其当做字典数据类型来处理。所以空集合请使用set()来创建
- 如果往集合中放入重复元素,将只会保留一个。 从字符串创建一个集合:
[75]:
s = “abcdefg”
st = set(s)
print(st)
{‘b’, ‘c’, ‘a’, ‘g’, ‘e’, ‘f’, ‘d’}
从列表创建一个集合:
[76]:
lst = [1, 2, 3]
st2 = set(lst)
print(st2)
{1, 2, 3}
从元组创建一个集合:
[77]:
tpl = (1, 2, 3, 4, 5)
st3 = set(tpl)
print(st3)
{1, 2, 3, 4, 5}
从字典创建一个集合,此时只会取key作为集合的元素:
[78]:
dct = {“1”: “zhangsan”, “2”: “lisi”}
st4 = set(dct)
print(st4)
{‘2’, ‘1’}
需要特别注意的是,set和list、tuple不一样,不能使用索引从中取出特定位置的元素,这主要是因为set是无序集合,我们并不能保证在各个平台、版本上集合元素的顺序 可以使用遍历(for item in set)的方法来逐个获取其中的元素,还可以将set转换成list或者tuple后再逐个获取元素。但需要强调的是,不要假设某个元素一定在某个位置上。
[79]:
str1 = “this is a book”
set1 = set(str1)
print(set1)
for i in set1:
print(i)
{‘t’, ‘h’, ‘b’, ‘k’, ‘s’, ‘a’, ‘ ‘, ‘o’, ‘i’}
t
h
b
k
s
a
o
i
集合操作
- add():往set中增加一个元素,如果该元素已经在set中,则不会成功。参数只能是单个元素,不能使list、tuple或者set
- update(seq):往set中添加多个元素。seq可以是字符串、tuple、list或者另一个set
- 需要注意:add()和update()都是字符串作为参数的时候,两者的区别:add()把字符串当做一个整体加入,而update()会将字符串中的单个字符逐个加入
- discard(item):从集合中删除指定的元素。
- remove(item):从集合中删除指定的元素。如果该元素不存在,会报错。
- pop():从集合中移除一个元素。因为集合是无序的,所以不能确保移除的是哪一个元素
- clear():清空整个集合
[80]:
# 初始化
myset = {1,3}
print(my_set)
my_set.add(2)
print(my_set)
# 加入多个元素
my_set.update([2,3,4])
print(my_set)
# 往集合中加入一个列表和另一个集合
my_set.update([4,5], {1,6,8})
print(my_set)
set2 = set(“abc”) # 会拆开字符串
print(set2)
set2.add(“def”) # 将def作为一个整体加入
print(set2)
set2.update(“xyz”) # 将xyz拆开成三个字母加入_
print(set2)
{1, 3}
{1, 2, 3}
{1, 2, 3, 4}
{1, 2, 3, 4, 5, 6, 8}
{‘a’, ‘b’, ‘c’}
{‘a’, ‘b’, ‘c’, ‘def’}
{‘x’, ‘b’, ‘y’, ‘c’, ‘def’, ‘a’, ‘z’}
集合运算
集合之间,可以进行集合操作,主要的集合操作有:
- 交集(intersection):两个集合操作,生成一个新的集合:只有两个集合中都有的元素,才会被放到新的集合中
- 可以使用运算符&或者函数intersection()来进行交集操作
- 并集(Union):两个集合生成一个新的集合,两个集合中的元素都会放到新的集合中
- 可以使用|操作符或者union()函数进行并集操作
- 差集(difference):两个集合生成新的集合,在原集合基础上,减去两者都有的元素,生成新的集合。
- 可以使用-操作符或者difference()函数来进行差集操作
- 对称差集( symmetric difference):两个集合生成新的集合,新集合中的元素是两个集合的元素减去两者一样的元素。
- 可以使用^操作符或者symmetric_difference()函数进行对称差集操作
[81]:
# 初始化两个集合
a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}
# 交集
print(a & b) # 使用&符号
print(a.intersection(b)) # 使用intersection()函数
# 并集
print(a | b) # 使用|符号
print(a.union(b)) # 使用union()函数
# 差集
print(a - b) # 使用-符号
print(a.difference(b)) # 使用difference()函数
# 对称差集
print(a ^ b) # 使用^操作符
print(a.symmetricdifference(b)) # 使用symmetricdifference()函数
{4, 5}
{4, 5}
{1, 2, 3, 4, 5, 6, 7, 8}
{1, 2, 3, 4, 5, 6, 7, 8}
{1, 2, 3}
{1, 2, 3}
{1, 2, 3, 6, 7, 8}
{1, 2, 3, 6, 7, 8}
其他操作:
- symmetric_difference_update()/ intersection_update()/ difference_update()/update():还是进行前面的对应交、并、差、对称差操作,但将运算的结果,更新到这个集合。
- isdisjoint():a.isdisjoint(b),a和b两个集合是否没有交集,没有交集返回True
- issubset():a.issubset(b),a是否为b的子集,是返回True
- issuperset():a.issuperset(b),a是否为包含b的所有元素,包含返回True
[82]:
# 使用xxx_update()
# 初始化两个集合
print(“intersection_update”)
a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}
a.intersection_update(b)
print(a)
print(b)
print(“difference_update”)
a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}
a.difference_update(b)
print(a)
print(b)
print(“symmetric_difference_update”)
a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}
a.symmetric_difference_update(b)
print(a)
print(b)
c = {1, 2, 3,