Python的列表&元组&字典&集合
列表(list)
列表(list)是python以及其他语言中最常用到的数据结构之一。Python使用中括号 [ ] 来解析列表。列表是可变的(mutable)——可以改变列表的内容。
列表是Python的序列类型之一,也支持索引、切片等操作。
列表的定义
list1 = ['Google', 'Runoob', 1997, 2000]
list2 = [1, 2, 3, 4, 5 ]
list3 = ["a", "b", "c", "d"]
与字符串的索引一样,列表索引从0开始。列表可以进行截取、组合等。
列表的查询
#!/usr/bin/env python
# -*-coding:utf-8-*-
"""
@author:fyh
@time:2019/5/31
"""
names = ['张三', "李四", "王五", "赵六"]
print(names[2])
print(names[0:3])
print(names[0:7])
print(names[-1])
print(names[0:3:1])
print(names[3:0:-1])
print(names[:])
增加数据
insert 方法用于将对象插入到列表中
append方法则用于在列表末尾追加新的对象
extend 方法可以在列表的末尾一次性追加另一个序列中的多个值。
案例1:
names_class2.append('aa')
names_class2.insert(2,'alvin')
print(names_class2)
>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> a.extend(b)
>>> a
[1, 2, 3, 4, 5, 6]
extend 方法修改了被扩展的列表,而原始的连接操作(+)则不然,它会返回一个全新的列表。
案例2:
>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> a.extend(b)
>>> a
[1, 2, 3, 4, 5, 6]
>>>
>>> a + b
[1, 2, 3, 4, 5, 6, 4, 5, 6]
>>> a
[1, 2, 3, 4, 5, 6]
修改数据
names_class2 = ['张三', '李四', '王五', '赵六']
names_class2[3] = '赵七'
names_class2[0:2] = ['su', 'alvin']
print(names_class2) # ['su', 'alvin', '王五', '赵七']
删除数据
#!/usr/bin/env python
# -*-coding:utf-8-*-
"""
@author:fyh
@time:2019/5/31
"""
names_class2 = ['张三', '李四', '王五', '赵六']
# 删除第一个元素del
del names_class2[0]
print(names_class2) # ['李四', '王五', '赵六']
# pop 默认删除的是最后一个元素 注意,pop是有一个返回值的,返回的是被删除的内容
name2 = names_class2.pop()
print(name2) # 赵六
print(names_class2) # ['李四', '王五']
# remove 需要指定删除的元素
names_class2.remove('李四')
print(names_class2)
# clear 清空列表
lst1 = [1, 2, 3, 4]
lst1.clear()
print(lst1) # []
其它常用操作
count
统计某个元素在列表中出现的次数
>>> ['to', 'be', 'or', 'not', 'to', 'be'].count('to')
>>> x = [[1,2], 1, 1, [2, 1, [1, 2]]]
>>> x.count(1)
>>> x.count([1,2])
index
从列表中找出某个值第一个匹配项的索引位置
names_class2 = ['张三', '李四', '王五', '赵六', '李四']
print(names_class2.index("李四")) # 1
reverse
reverse 方法将列表中的元素进行反转
list1 = ['s', 'b', 'c', 'd']
list1.reverse()
print(list1) # 结果为:['d', 'c', 'b', 's']
sort
sort用于列表排序
x = [4, 6, 2, 1, 7, 9]
# 正序
x.sort()
print(x) # [1, 2, 4, 6, 7, 9]
# 倒序
x.sort(reverse=True)
print(x) # [9, 7, 6, 4, 2, 1]
元组(tuple)
- python中元组与列表很类似,为只读列表,即数据可以被查询,但不能被修改,所以,列表的切片操作同样适用于元组。
- 元组写在小括号()里,元素之间用逗号隔开。
- 另外,元组的意义还在于,元组可以在映射(和集合的成员)中当作键使用——而列表则不行;元组作为很多内建函数和方法的返回值存在。
tup1 = ('a', 'b', 'c', 'd', 11, 12)
print(tup1[0])
print(tup1[0:3])
print(len(tup1))
元组的拆包
元组拆包可以应用到任何可迭代对象上, 唯一的硬性要求是, 被可迭代对象中的元素数量必须要跟接受这些元素的元组的空档数一致。 除非我们用 * 来表示忽略多余的元素
#!/usr/bin/env python
# -*-coding:utf-8-*-
"""
@author:fyh
@time:2019/7/9
"""
# 平行赋值拆包
a, b = (11, 22)
print(a) # 11
print(b) # 22
# 优雅的写法: 数据交换
a, b = b, a
# 用_来替代
_, _, c = (33, 44, 55)
print(c) # 55
# 用*来替代
a1, *a2, a3 = (11, 22, 33, 44, 55, 66)
print(a1) # 11
print(a2) # [22, 33, 44, 55]
print(a3) # 66
具名元组
collections.namedtuple 是一个工厂函数, 它可以用来构建一个带字段名的元组和一个有名字的类——这个带名字的类对调试程序有很大帮助。
用 namedtuple 构建的类的实例所消耗的内存跟元组是一样的, 因为字段名都被存在对应的类里面。 这个实例跟普通的对象实例比起来也要小一些, 因为 Python不会用 dict 来存放这些实例的属性。
#!/usr/bin/env python
# -*-coding:utf-8-*-
"""
@author:fyh
@time:2019/7/9
"""
import collections
"""
创建一个具名元组需要两个参数, 一个是类名, 另一个是类的各个字段的名字。 后者可以是由数个字符串组成的可迭代对象, 或者是由空格分隔开的字段名组成的字符串。
存放在对应字段里的数据要以一串参数的形式传入到构造函数中(注意, 元组的构造函数却只接受单一的可迭代对象)
你可以通过字段名或者位置来获取一个字段的信息
"""
city = collections.namedtuple('City', 'name country population coordinates')
tokyo = city('Tokyo', 'JP', 36.933, (25.689722, 129.691667))
print(tokyo) # City(name='Tokyo', country='JP', population=36.933, coordinates=(25.689722, 129.691667))
print(type(tokyo)) # <class '__main__.City'>
print(tokyo.name) # Tokyo
# 具名元组专有的类属性 _fields 属性是一个包含这个类所有字段名称的元组。
print(tokyo._fields) # ('name', 'country', 'population', 'coordinates')
# 用 _make() 通过接受一个可迭代对象来生成这个类的一个实例, 它的作用跟City(*delhi_data) 是一样的
delhi_data = ('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889))
delhi = city._make(delhi_data)
print(delhi)
# _asdict() 把具名元组以 collections.OrderedDict 的形式返回, 我们可以利用它来把元组里的信息友好地呈现出来。
print(delhi._asdict()) # OrderedDict([('name', 'Delhi NCR'), ('country', 'IN'), ('population', 21.935), ('coordinates', (28.613889, 77.208889))])
字典(dict)
字典是python中唯一的映射类型,采用键值对(key-value)的形式存储数据。python对key进行哈希函数运算,根据计算的结果决定value的存储地址,所以字典是无序存储的,且key必须是可哈希的。可哈希表示key必须是不可变类型,如:数字、字符串、元组。
字典(dictionary)是除列表之外python之中最灵活的内置数据结构类型。列表是有序的对象结合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。
创建字典
#!/usr/bin/env python
# -*-coding:utf-8-*-
"""
@author:fyh
@time:2019/5/31
"""
# 方式一
dic1 = {
"name": "zhangsan",
"age": 36,
"sex": "female"
}
print(dic1) # {'name': 'zhangsan', 'age': 36, 'sex': 'female'}
# 方式二
dic2 = dict((("name", "abc"), ))
print(dic2) # {'name': 'abc'}
# 空字典
dic3 = dict()
print(dic3) # {}
# 或者
dic4 = {}
字典添加数据
#!/usr/bin/env python
# -*-coding:utf-8-*-
"""
@author:fyh
@time:2019/5/31
"""
dic1 = dict()
dic1['name'] = 'zhangsan'
dic1['age'] = 18
print(dic1) # {'name': 'zhangsan', 'age': 18}
# 如果键不存在于字典中,将会添加键并将值设为default,如果存在,则不会做任何操作
a = dic1.setdefault('name', 'abc')
print(a) # zhangsan
b = dic1.setdefault('cc', 'dd')
print(b) # dd
print(dic1) # {'name': 'zhangsan', 'age': 18, 'cc': 'dd'}
查询字典数据
#!/usr/bin/env python
# -*-coding:utf-8-*-
"""
@author:fyh
@time:2019/5/31
"""
dic3 = {'name': 'aa', 'age': 18}
print(dic3['name']) # aa
# print(dic3['names']) # 字典中没有这个key时,会报错KeyError: 'names'
print(dic3.get('age', False)) # 18
print(dic3.get('ages', False)) # get不到key时,会返回默认值False
# items 以列表返回可遍历的(键, 值) 元组数组
print(dic3.items())
# keys返回一个迭代器,可以使用 list() 来转换为列表,包含字典的额所有的键
print(dic3.keys())
# 返回一个迭代器,可以使用 list() 来转换为列表,包含字典的所有value
print(dic3.values())
# 用成员运算符 in 判断key是否在字典中
print('name' in dic3) # python2中用has_key判断 dic3.has_key('name')
print(list(dic3.values()))
修改字典数据
#!/usr/bin/env python
# -*-coding:utf-8-*-
"""
@author:fyh
@time:2019/5/31
"""
dic3 = {'name': 'aa', 'age': 18}
dic3["name"] = "alivn"
print(dic3) # {'name': 'alivn', 'age': 18}
# update 把字典dict4的键/值对更新到dict3里
dic4 = {'sex': 'male', 'hobby': 'girl', 'age': 36}
dic3.update(dic4)
print(dic3) # {'name': 'alivn', 'age': 36, 'sex': 'male', 'hobby': 'girl'}
删除字典数据
#!/usr/bin/env python
# -*-coding:utf-8-*-
"""
@author:fyh
@time:2019/5/31
"""
dic3 = {'name': 'aa', 'age': 18}
# 删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。
aa = dic3.pop('name')
print(aa) # aa
print(dic3) # {'age': 18}
# clear() 删除字典内所有元素
dic3.clear()
print(dic3) # {}
# del 删除字典中指定的键值对
dic4 = {"name": "cc", "age": 19, "male": "sex"}
del dic4["name"]
print(dic4) # {'age': 19, 'male': 'sex'}
# 删除字典,包括变量的内存空间
del dic4
print(dic4) # 报错 NameError: name 'dic4' is not defined
其它操作
#!/usr/bin/env python
# -*-coding:utf-8-*-
"""
@author:fyh
@time:2019/5/31
"""
# fromkeys 创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值
d1 = dict.fromkeys(['host1', 'host2', 'host3'], 'Mac')
print(d1) # {'host1': 'Mac', 'host2': 'Mac', 'host3': 'Mac'}
d1['host1'] = 'xiaomi'
print(d1)
#######
d2 = dict.fromkeys(['host1', 'host2', 'host3'], ['Mac', 'huawei'])
print(d2)
# 结果:{'host1': ['Mac', 'huawei'], 'host2': ['Mac', 'huawei'], 'host3': ['Mac', 'huawei']}
d2['host1'][0] = 'xiaomi'
print(d2)
dic = {"a": "123"}
dic1 = dic.fromkeys("王健林", "王思聪")
print(dic1) # 结果:{'王': '王思聪', '健': '王思聪', '林': '王思聪'}
字典的遍历
字典的嵌套操作:
av_catalog = {
"欧美": {
"www.youporn.com": ["很多免费的,世界最大的","质量一般"],
"www.pornhub.com": ["很多免费的,也很大","质量比yourporn高点"],
"letmedothistoyou.com": ["多是自拍,高质量图片很多","资源不多,更新慢"],
"x-art.com":["质量很高,真的很高","全部收费,屌比请绕过"]
},
"日韩":{
"tokyo-hot":["质量怎样不清楚,个人已经不喜欢日韩范了","听说是收费的"]
},
"大陆":{
"1024":["全部免费,真好,好人一生平安","服务器在国外,慢"]
}
}
av_catalog["大陆"]["1024"][1] += ",可以用爬虫爬下来"
print(av_catalog["大陆"]["1024"])
#ouput ['全部免费,真好,好人一生平安', '服务器在国外,慢,可以用爬虫爬下来']
字典的遍历:
#!/usr/bin/env python
# -*-coding:utf-8-*-
"""
@author:fyh
@time:2019/5/31
"""
s
dic1 = {
"name": "aaa",
"age": 18,
'sex': "male"
}
for key, value in dic1.items():
print(key, value)
"""
结果:
name aaa
age 18
sex male
"""
案例1:实现三级菜单的遍历
#!/usr/bin/env python
# -*-coding:utf-8-*-
"""
@author:fyh
@time:2019/5/31
"""
data = {
'山东': {
'青岛': ['四方', '黄岛', '崂山', '李沧', '城阳'],
'济南': ['历城', '槐荫', '高新', '长青', '章丘'],
'烟台': ['龙口', '莱山', '牟平', '蓬莱', '招远']
},
'江苏': {
'苏州': ['沧浪', '相城', '平江', '吴中', '昆山'],
'南京': ['白下', '秦淮', '浦口', '栖霞', '江宁'],
'无锡': ['崇安', '南长', '北塘', '锡山', '江阴']
},
}
exit_flag = False # 设置全局变量,用来退出循环,实现任意一级菜单都可以退出
while not exit_flag:
for i1 in data: # 读取第一级菜单
print(i1)
choice = input('选择进入1,第一级,按q退出:')
if choice in data:
while not exit_flag:
for i2 in data[choice]: # 读取第二级菜单
print(i2)
choice2 = input('选择进入2,按b返回上一级,按q退出:')
if choice2 in data[choice]:
while not exit_flag:
for i3 in data[choice][choice2]: # 读取第三级菜单
print(i3)
choice3 = input('选择进入3,按b返回上一级,按q退出:')
if choice3 in data[choice][choice2]:
for i4 in data[choice][choice2][choice3]:
print(i4)
choice4 = input('最后一层,按b返回上一级,按q退出:')
if choice4 == 'b':
pass # 占位符
if choice4 == 'q':
exit_flag = True
if choice3 == 'b':
break
if choice3 == 'q':
exit_flag = True
if choice2 == 'b':
break
if choice2 == 'q':
exit_flag = True
if choice == 'q':
exit_flag = True
集合(set)
集合是一个无序的,不重复的数据组合,它的主要作用如下:
- 去重,把一个列表变成集合,就自动去重了
- 关系测试,测试两组数据之前的交集、差集、并集等关系
集合(set):把不同的元素组成一起形成集合,是python基本的数据类型。
集合中的元素必须是可hash的,但是set本身是不可hash的
集合元素(set elements):组成集合的成员(不可重复)
集合的分类:
- 可变集合(set):可添加和删除元素,非可哈希的,不能用作字典的键,也不能做其他集合的元素
- 不可变集合(frozenset): 与上面正好相反
初识集合:
li = [1, 2, 'a', 'b']
s = set(li)
print(s) # {1, 2, 'a', 'b'}
li2 = [1, 2, 1, 'a', 'a']
s = set(li2)
print(s) # {1, 2, 'a'}
集合不允许嵌套:
li = [[1, 2], 'a', 'b']
s = set(li) # TypeError: unhashable type: 'list'
print(s)
集合的创建
由于集合没有自己的语法格式,只能通过集合的工厂方法set()和frozenset()创建
s1 = set('alvin')
s2 = frozenset('yuan')
print(s1, type(s1)) # {'l', 'v', 'i', 'a', 'n'} <class 'set'>
print(s2, type(s2)) # frozenset({'n', 'y', 'a', 'u'}) <class 'frozenset'>
集合用作字典的键:
lst1 = [1, 2, 4]
# dic1 = {set(lst1): "aa"} # TypeError: unhashable type: 'set'
# 字典的键可以是不可变集合,可hash的,不能是可变集合
aa = frozenset(lst1)
dic1 = {aa: "bb"}
print(dic1) # {frozenset({1, 2, 4}): 'bb'}
访问集合
s1 = set('alvin')
print('a' in s1)
print('b' in s1)
# s1[1] #TypeError: 'set' object does not support indexing
for i in s1:
print(i)
#
# True
# False
# v
# n
# l
# i
更新集合
s.add()
s.update()
s.remove()
注意只有可变集合才能更新
# s1 = frozenset('alvin')
# s1.add(0) # AttributeError: 'frozenset' object has no attribute 'add'
s2 = set('alvin')
s2.add('mm')
print(s2) # {'mm', 'l', 'n', 'a', 'i', 'v'}
s2.update('HO') # 添加多个元素
print(s2) # {'mm', 'l', 'n', 'a', 'i', 'H', 'O', 'v'}
s2.remove('l')
print(s2) # {'mm', 'n', 'a', 'i', 'H', 'O', 'v'}
删除集合
del 可以删除集合
集合的操作符
- in ,not in
- 集合等价与不等价(==, !=)
- 子集、超集
#!/usr/bin/env python
# -*-coding:utf-8-*-
"""
@author:fyh
@time:2019/5/31
"""
# 联合 联合(union)操作与集合的or操作其实等价的,联合符号有个等价的方法,union()。
s1 = set('alvin')
s2 = set('yuan')
s3 = s1|s2
print(s3) # {'a', 'l', 'i', 'n', 'y', 'v', 'u'}
print(s1.union(s2)) # {'a', 'l', 'i', 'n', 'y', 'v', 'u'}
# 交集 与集合and等价,交集符号的等价方法是intersection()
a1 = set('alvin')
a2 = set('yuan')
a3 = a1 & a2
print(a3) # {'n', 'a'}
print(s1.intersection(s2)) # {'n', 'a'}
# 差集 等价方法是difference()
b1 = set('alvin')
b2 = set('yuan')
b3 = b1 - b2
print(b3) # {'v', 'i', 'l'}
print(s1.difference(s2)) # {'v', 'i', 'l'}
# 对称差集 等价方法symmetric_difference
c1 = set('alvin')
c2 = set('yuan')
c3 = c1 ^ c2
print(c3) # {'l', 'v', 'y', 'u', 'i'}
print(s1.symmetric_difference(s2)) # {'l', 'v', 'y', 'u', 'i'}
集合应用
'''最简单的去重方式'''
lis = [1,2,3,4,1,2,3,4]
print(list(set(lis))) #[1, 2, 3, 4]