Python 元组与字典

元组与字典
元组

元组是Python中一种常用的数据结构,元组可以由多个元素组成,每个元素可以存储不同类型的数据,如字符串,数字,元组等。元组是写保护的即元组创建后就不能在做任何修改操作。一般当我们希望数据不改变时,我们使用元组,其他情况下基本都用列表。

元组的创建

Tuple(元组)是Python内置的的一种数据结构,元组由一系列元素组成,所有的元素都包含在一对圆括号()当中。

  1. 创建一个空元组,只需要一对空的小括号
    tuple = ()
tuple = ()
print(type(tuple))
print(tuple)
<class 'tuple'>
()
  1. 创建的元组只包含唯一一个元素
    这里通常很容易忽略单元素后的逗号,不添加都好Python解释器无法区分出元组,例如
tuple = ("apple")
print(tuple[0])
print(type(tuple))
a
<class 'str'>

这段代码的初衷是输出元组tuple的第一个元素apple,然后这里输出的结果是a。因为Python解释器并没有将tuple识别为Tuple(元组)类型,而时将它当作字符串类型,所以输出的并不是我们期望的值

所以创建唯一元素的元组,需要在元素的后面添加一个逗号,使python解释器可以识别出元组中的元素。如下所示将输出tuple元组中的唯一的元素apple

tuple = ("apple",)
print(tuple[0])
print(type(tuple))
apple
<class 'tuple'>

所以定义单元素元组的时候大家要注意。

# # 所以如果创建的不是空元组,小括号中至少有一个都好
tuple1 = (10,)
print(type(tuple1))
# # 加了逗号,不加括号也是可以的,当你只赋值给一个变量
tuple2 =10,
print(type(tuple2))
<class 'tuple'>
<class 'tuple'>
元组的访问

元组使不可变的序列,所以可以通过索引或者切片去访问。元组因为写保护,不能添加或者删除任何元素,因此不存在任何添加或者删除的方法。

tuple = (6,"apple",(8,6,8),True,"你好")
# 通过索引取出第二个元素
print(tuple[1])
# 通过分片(省略默认步长为1)
print(tuple[1:3])
# 通过负数索引取值,步长为1省略,取数方向由左向右,左开右闭原则
print(tuple[-1])
print(tuple[0:-2])
print(tuple[2:-2])
apple
('apple', (8, 6, 8))
你好
(6, 'apple', (8, 6, 8))
((8, 6, 8),)

这里引入一个概念 打包和解包。创建元组的过程,python中称为打包,相反则元组可以执行解包的操作。解包就是将元组中的各个元素分别赋值给多个变量,这样可以避免使用循环遍历来获取每个元素的值。

# 打包
tuple = ["张三","李四","王二","刘六"]
# 解包,元组中有4个元素,然后用4个变量接收
a,b,c,d = tuple
print(a,b,c,d)
# 解包,用通配符* 去接收元组中定义的值
'''
a,*b 将元组分成两部分,a 则用来接收元组解包的第一个元素,*b则用来接收剩余的部分
同理"
*a,b 将元组分成两部分,b 则用来接收元组解包的最后一个元组.*a则用来接收前面的部分
如若这样呢? a,*b,c = tuple
a,*b,c 将元组分成3部分,a 用于接收第一个元素,c 用于接收最后一个元素,*b 用于接收中间的部分
注意: 一个语句不能同时包含两个*, 例如,*a,*b,c = tuple
'''
a,*b = tuple
print("a =",a)
print("*b =",b)

*a,b = tuple
print("*a =",a)
print("b =",b)

a,*b,c = tuple
print("a =",a)
print("*b =",b)
print("c =",c)
张三 李四 王二 刘六
a = 张三
*b = ['李四', '王二', '刘六']
*a = ['张三', '李四', '王二']
b = 刘六
a = 张三
*b = ['李四', '王二']
c = 刘六
元组的遍历

元组的遍历就是指通过循环语句依次范文元组中各元素的值,遍历通常会用到两个函数len()和range(),上篇文章说列表的时候已提到过range()函数的定义,用两段小代码演示一下

tuple = (("爸爸","妈妈"),("爷爷","奶奶"),("哥哥","姐姐"))
# print(tuple)
#遍历元组
for i in tuple:
    print(i)
    #遍历子元组
    for j in i:
        print(j)
('爸爸', '妈妈')
爸爸
妈妈
('爷爷', '奶奶')
爷爷
奶奶
('哥哥', '姐姐')
哥哥
姐姐
tuple = (("爸爸","妈妈"),("爷爷","奶奶"),("哥哥","姐姐"))
#print(len(tuple))
# 这里仅仅是展示range 和len的搭配使用, 上面的直接遍历操作更直观
for i in range(len(tuple)):
    print(tuple[i])
    for j in range(len(tuple[i])):
        print(tuple[i][j])
字典

字典是python中重要的数据结构,字典由”键-值“对组成的集合,通过”键“来查找”值“,这里没有索引一说了。

字典的创建

字典是由一系列的”键-值“ (key-value)对组成,”键-值“对之间用逗号隔开,并且包含在一对花括号{}当中,创建的的格式 dict = {key1:value1,key2:value2,…}

  1. 创建一个空字典,一对花括号就可以了
dict1 = {}
print(dict1)
print(type(dict1))
{}
<class 'dict'>
  1. 创建非空字典
  • 直接将键值对包含在包含在花括号{}里面
dict1 = {"name":"hello","age":30,"gender":"F"}
print(dict1)
  • 用关键字dict()转化
dict2 = dict(name="hello",age=30,gender="F")
print(dict2)
  • 用关键字dict()转化双值子序列为一个Item,键值对

双值序列:[1,2],“ab”,(1,2) 等都是包含两个元素的序列
双值子序列[(1,2)], ((“name”,“张三”),(“age”,30)) 这种一个序列的子集,每个元素也是由两个值组成的

dict3 = dict([("name","hello"),("age",30),("gender","F")])
print(dict3)

注意:字典的键key是却分大小写的,而且字典的键是不能重复的,如果出现重复的后面的会替换前面的 ,下面用代码演示一下

dict1 = {"a":"hello","b":"Python","A":"hi"}
print(dict1["a"])
print(dict1["A"])
hello
hi

各自输出对应的value值,但是如果有key重复呢?可以看到value “hi” 把 ”hello“ 给覆盖掉了

dict1 = {"a":"hello","b":"Python","a":"hi"}
print(dict1)
print(dict1["a"])
{'a': 'hi', 'b': 'Python'}
hi
字典的访问(增删改查操作)

字典的访问与元组,列表有所不同,元组和列表是通过索引来获取对应的值,而字典是通过key来获取对应的value的,所以格式 value = dict[“key”]

  • 查找 (通过key来获取value)
    value = dict[key]
dict1 = {"name":"hello","age":30,"gender":"F"}
print(dict1["name"])

方法get(key),以dict1.get(key)方式获取value和直接通过dict1[key]的区别

dict1 = {"name":"hello","age":30,"gender":"F"}
# 当查找的key是存在的情况下,效果是一样的输出对应的值
print(dict1["name"])
print(dict1.get("name"))
# 当查找的key是不存在的情况下
print(dict1["height"])   # 直接报错 KeyError: 'height' 因为字典dict1中没有这个key
print(dict1.get("height")) # 返回空值 None, 不会报错

  • 修改/增加
    1.dict[key] = value
    如果key值已经存在,则执行修改操作,将字典中原有的key对应的value值给覆盖掉;反之如果key 值不存在,则将定义的这一组key-value值添加到字典当中
dict1 = {"name":"hello","age":30,"gender":"F"}
# key height 不存在原有的字典中,则完成追加操作
dict1["height"] = 180
print(dict1)
# key name 已经存在的于字典当中,则完成修改操作,将name 由 hello 改成 hi
dict1["name"] = "hi"
print(dict1["name"])
print(dict1)
{'name': 'hello', 'age': 30, 'gender': 'F', 'height': 180}
hi
{'name': 'hi', 'age': 30, 'gender': 'F', 'height': 180}
  1. dict.setdefault(key, value)
    其中value值可以省略,默认为None。
    如果key值已经存在于字典当中,不会对字典由任何改变; 反之如果不存在则将定义的key-value给添加到字典当中
dict1 = {"name":"hello","age":30,"gender":"F"}
# key name已经存在不会对原有的hello有任何影响
dict1.setdefault("name","hi")
print(dict1["name"])
print(dict1)
# key height 不存在,则会添加到字典当中
dict1.setdefault("height",180)
print(dict1["height"])
print(dict1)
hello
{'name': 'hello', 'age': 30, 'gender': 'F'}
180
{'name': 'hello', 'age': 30, 'gender': 'F', 'height': 180}
  1. update()
    将其他字典的key-value添加到当前的字典当中 (和列表的extend 方法类似)
dict1 = {"name":"hello","age":30,"gender":"F"}
dict2 = {"height":180}
dict1.update(dict2)
print(dict1)
  • 删除
    1.del 删除字典中的key-value
dict1 = {"name":"hello","age":30,"gender":"F"}
# 从字典dict1中删除gender 
del dict1["gender"]
print(dict1)
{'name': 'hello', 'age': 30}
  1. popitem()
    删除字典最后的一个key-value 这个方法是有返回值的。删除之后它会将删除的key-value作为返回值返回.
dict1 = {"name":"hello","age":30,"gender":"F"}
# 用来删除字典的最后一个元素,有返回值(被删除的key-value)
res = dict1.popitem()
print(res)
print(dict1)
('gender', 'F')
{'name': 'hello', 'age': 30}
  1. pop(key[,default vaule])
    根据key删除指定的value。第二个参数可以指定一个默认值,当获取不到值的时候会返回默认值.如果key已经存在,返回值是key对应的value.
dict1 = {"name":"hello","age":30,"gender":"F"}
# 删除一个不存在的key
res = dict1.pop("height","不低于180")
print(res)
print(dict1)
# 删除一个已经存在于字典的key gender
res = dict1.pop("gender","无性别")
print(res)
print(dict1)
不低于180
{'name': 'hello', 'age': 30, 'gender': 'F'}
F
{'name': 'hello', 'age': 30}
  1. clear()
    用于清空字典,过后字典为空字典
dict1 = {"name":"hello","age":30,"gender":"F"}
dict1.clear()
print(dict1)
{}
字典的拷贝

copy()
copy() 方法用来对字典进行潜复制
注意:潜复制只会复制字典本身,如果字典中还有个字典是不会进行复制的

这里要补充说明深拷贝浅拷贝的区别
对象的构成由(id,value,type),python赋值操作或函数参数传递永远是对象引用(即id),而不是对象内容。在Python中一切皆对象,对象又分为可变(mutable)和不可变(immutable)两种类型。

对象拷贝是指在内存中创建新的对象,产生新的内存地址。当顶层对象和它的子元素对象全都是immutable不可变对象时就不存在被拷贝,因为没有新对象产生。

浅拷贝(Shallow Copy):拷贝顶层对象,但不会拷贝内部的子元素对象。
深拷贝(Deep Copy):递归拷贝顶层对象,以及它内部的子元素对象

'''
a=[1,"string",(2,3,4)]
b=copy.copy(a)  # 浅拷贝
b=copy.deepcopy(a) # 深拷贝
顶层对象可变,子对象不可变 (深拷贝和浅拷贝效果一样)
深拷贝 变量a与变量b指向不同的列表对象,修改a[1]只是将列表a的第一个元素重新指向新对象,不会影响b[1]
浅拷贝 变量a与变量b指向不同的列表对象,修改a[1]只是将列表a的第一个元素重新指向新对象,不会影响b[1]

a=[1,"string",[2,3,4]]
b=copy.copy(a)  # 浅拷贝
b=copy.deepcopy(a)  # 深拷贝
顶层对象可变,子对象包含有可变:(深拷贝可变子对象值的修改相互独立)
深拷贝 既拷贝了顶层对象,又递归拷贝了子元素对象,所以a[2]与b[2]指向了两个不同的列表对象,修改a[2][1] = 'world'后,
       它重新指向了新对象,不会影响到b[2][1]
浅拷贝 copy.copy()只拷贝了顶层对象,没有拷贝子元素对象[2,3,4],即a[2]和b[2]指向同一个列表对象,修改a[2]同时也改变了b[2]

a=(1,"string",(2,3,4))
b=copy.copy(a)  # 浅拷贝
b=copy.deepcopy(a) # 深拷贝
顶层对象不可变,子对象不可变(深拷贝和浅拷贝效果一样)
深拷贝 变量a与变量b指向的是同一个元组对象,没有拷贝
浅拷贝 变量a与变量b指向的是同一个元组对象,没有拷贝

a=(1,"string",[2,3,4])
b=copy.copy(a)
b=copy.deepcopy(a)
顶层对象不可变,子对象包含可变
深拷贝 通过id值可以看到变量a与b指向的是不同的元组对象,a[2]和b[2]指向不同的列表对象,所以修改a[2][1]不会影响b[2][1]
浅拷贝 通过id值可以看到变量a和b指向同一个元组对象,a[2]和b[2]指向同一个列表对象,修改a[2]的同时b[2]也会改变

'''
字典的遍历

我们主要可以通过3种方式对字典进行遍历
• keys() 该方法返回字典所有的key
• values() 该方法返回一个序列 序列中保存有字典的值
• items() 该方法会返回字典中所有的项 它返回一个序列,序列中包含有双值子序列 双值分别是 字典中的key和value

dict1 ={"name":"张三","age":"30","gender":"F"}
print(dict1.keys())
for i in dict1.keys():
    print(i)
    
print(dict1.values())
for i in dict1.values():
    print(i)
    
for k,v in dict1.items():
    print(k,v)

在这里插入图片描述
练习
1.给 用户9次机会 猜1 - 10 个数字随机来猜数字。如果随机的数字和用户输入的数字一致则表示正确,如果不一致则表示错误。最终结果要求用户怎么也猜不对

print("你有9次机会参与抽奖,大奖等待你的参与!!!")
i=1
while(i <= 9):
    print("第%d次机会:" % i)
    j = int(input("请输入抽奖号码[1-10]:"))
    # 生成 1-10的列表
    lst = list(range(1,11))
    # 从列表中移除用户输入的数字
    lst.remove(j)
    # print(lst)
    if(j not in lst):
        if(9-i !=0):
            print("很遗憾你没有中奖!你还有%d次机会" % (9-i))
        else:
            print("机会用完了.很遗憾你没有中奖.")
            break
    res = input("continue or not[y/n]:")
    # print(res)
    if(res == "y" or res == "Y"):
        i += 1
        continue
    else:
        print("再见!")
        break

2.现在有8位老师,3个办公室,要求将8位老师随机的分配到三个办公室中

import random
Teacher = ["赵","钱","孙","李","周","吴","郑","王"]
# print(Teacher)
# 定义一个office列表,内部共有三个元素
office = [[],[],[]]
i = 8
while(i > 0):
#  随机选出一个老师
    a = random.choice(Teacher)
    Teacher.remove(a)
# 随机选出一个办公室编号
    k = random.randint(0,2)
    office[k].append(a)
    i -= 1
# 遍历办公室列表
for j in office:
    print(j)

3.如果需要每间office最少一个人的话,对办公室的人数做限制>0

import random
Teacher = ["赵","钱","孙","李","周","吴","郑","王"]
# print(Teacher)
# 定义一个office列表,内部共有三个元素
office = [[],[],[]]
# 生成一个长度为8的随机数列表,用来限制人数
while(True):
    lst = [random.randint(0, 2) for _ in range(8)]
    if(lst.count(0) ==0 or lst.count(1)==0 or lst.count(2)==0):
        continue
    else:
        for k in lst:
            a = random.choice(Teacher)
            Teacher.remove(a)
            office[k].append(a)
        break

# 遍历办公室列表
for j in office:
    print(j)

4.a = {“name”:“123”,“data”:{“result”:[{“src”:“python1”},{“src”:“python2”},{“src”:“python3”}]}}
找到python1/python2/python3

a = {
    "name":"123",
     "data":
         {
         "result":[{"src":"python1"},
                   {"src":"python2"},
                   {"src":"python3"}
                   ]
         }
     }
for i in a["data"]["result"]:
    print(i.get("src"))

5.有如下值列表[11,22,33,44,55,66,77,88,99,90], 将所有大于66的值保存至字典的第一个key的值中,将小于66值保存至第二个key的值中

lst = [11,22,33,44,55,66,77,88,99,90]
dict1 = {">=66":[],"<66":[]}
# print(dict1[">= 66"])
# print(dict1["<66"])
for i in lst:
    if(i<66):
        dict1["<66"].append(i)
    else:
        dict1[">=66"].append(i)
print(dict1)
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值