2021-03-17

1-1集合简介

  • 集合表现形式set 集合和列表非常相似
  • 不同点
    集合只能存储不可变对象
    集合中存储的对象是无序的
    集合不能出现重复元素
    **
  • 使用{}来创建集合
  • 可以通过set()来将序列和字典转换成集合
  • len() 使用len()来获取集合中元素的数量
  • add()像集合中添加元素
  • update()将一个集合中的元素添加到另一个集合当中
  • pop()随机删除集合中的一个元素一般是删除最后一个元素
  • remove() 删除集合中指定的元素
  • clear() 清空集合

集合(set)是一个无序的不重复元素序列。。
可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { }
是用来创建一个空字典。

创建格式:

parame = {value01,value02,…} 或者 set(value)

# set表示集合 {}
# set1 ={[1, 2, 3]}  # 存储可变对象时会报错
# print(set1)

# set2 = {6, 7, 8}
# print(set2)
# print(set[2]) # 无序是没有索引,存储到内存里并不知数据的顺序

set3 = {2, 2, 3, 3, 4, 4}
print(set3)
# 根据集合的特性,我们 可以做去重操作

set1 = {}  # 这个只是创建了空字典
print(type(set1))

set2 = set() # 创建空集合
print(type(set2))

tuple1 = ()
print(type(tuple1))   # 创建空元组无意义,因为元组不可变

# 强制转换为集合的业务场景 去重
list1 = [1, 1, 2, 2, 3, 3, 4, 4]
set3 = set(list1)
print(set3)

相应运行结果
{2, 3, 4}
<class 'dict'>
<class 'set'>
<class 'tuple'>
{1, 2, 3, 4}

集合的使用

# set.add() 向集合加入元素
set1 = set()
set1.add(1)
print(set1)

# set.update() 将一个集合添加到另一个集合中
set2 = {2, 3}
set1.update(set2)
print(set1)

# len() in not in
# del set1[0]  #集合存储无序 因此,无法根据索引来del
set3 = set1.copy()
print(set3)

set1.clear()
print(set1)
相应运行结果:
{1}
{1, 2, 3}
{1, 2, 3}
set()

s.remove( x ) 将元素 x 从集合 s 中移除,如果元素不存在,则会发生错误。
在这里插入图片描述

s.discard( x )
此外还有一个方法也是移除集合中的元素,且如果元素不存在,不会发生错误。格式如下所示:
在这里插入图片描述

s.pop() thisset = set((“Google”, “Runoob”, “Taobao”, “Facebook”)) x =
thisset.pop()

输出结果为 print(x) $ python3 test.py Runoob 多次执行测试结果都不一样。

set 集合的 pop 方法会对集合进行无序的排列,然后将这个无序排列集合的左面第一个元素进行删除。

集合内置方法完整列表
在这里插入图片描述

1-2集合的运算

set1 = {1, 2, 3, 4, 5, 6}
set2 = {4, 5, 6, 7, 8, 9}
print(set1 & set2)
# 交集 查看相同的部分元素

# 并集 两个集合并集得到的是一个都涵盖两个集合的元素
print(set1 | set2)

# 差集 减去相同的部分 得到结果为前一个集合剩余部分
print(set1 - set2)
print(set2 - set1)

# 异或集 去掉两个集合相同的部分 然后合并一起
print(set1 ^ set2)

set3 = {1, 2, 3, 4, 5, 6}
set4 = {1, 2, 3, 4, 5, 6, 7, 8, 9}
print(set3 < set4)
相应运行结果
{4, 5, 6}
{1, 2, 3, 4, 5, 6, 7, 8, 9}
{1, 2, 3}
{8, 9, 7}
{1, 2, 3, 7, 8, 9}
True

1-3 浅拷贝与深拷贝

直接赋值:其实就是对象的引用(别名)。

浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。

深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。

字典浅拷贝实例
在这里插入图片描述
深度拷贝需要引入 copy 模块
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

# 浅拷贝

# dict2 = {
#     'a': 1,
#     'b': 2
#
# }
#
# print(id(dict1), id(dict2))
# a = 'ab'
# b = 'ab'
#
# print(id(a), id(b))

# 方式一
# dict2 = dict1.copy()
# print(id(dict1), id(dict2))

# 方式二
import  copy
# dict2 = copy.copy(dict1)
#
# print(id(dict1), id(dict2))

# 深拷贝
# dict1 = {
#     'a': 1,
#     'b': [1, 2, 3]
#
# }

# dict2 = copy.copy(dict1)  # 浅拷贝
# print(id(dict1), id(dict2))
# dict1['b'][0] = 10
# print(id(dict1['b']))
# print(id(dict2['b']))
# print(dict1, dict2)

dict1 = {
    'a': 1,
    'b': [1, 2, 3]

}

dict2 = copy.deepcopy(dict1) # 深拷贝
print(id(dict1), id(dict2))
dict1['b'][0] = 10
print(id(dict1['b']))
print(id(dict2['b']))
print(dict1, dict2)
相应运行结果:

2923646312024 2923647160256
2923648661256
2923648661448
{'a': 1, 'b': [10, 2, 3]} {'a': 1, 'b': [1, 2, 3]}

1-4 函数

1-4-1 函数简介

• 函数也是一个对象
• 函数用来保存一些可执行的代码,并且可以在需要时,对这些语句进行多次调用

语法
def 函数名([形参1,形参2,形参3....])
    代码块

注意:
函数名必须符合标识符的规范(可以包含字母、数字、下划线但是不能以数字开头)
print是函数对象 print()是调用函数

def fun(a, b):  # 这个括号里叫做形参 也叫形式上参数
    # a = 1
    # b = 2
    print(a + b)


fun(1, 2)    # 此括号里为实参 实际参数 ,当你调用的时候传递实际参数
fun(1342434, 3453545)

1-4-2 函数的参数

1-4-2.1 形参和实参
  • 形参(形式参数) 定义形参就相当于在函数内部声明了变量,但是并不是赋值
  • 实参(实际参数)指定了形参,那么在调用函数时必须传递实参,实参将会赋值给对应的形参,简单来说有几个形参就要有几个实参
def fun(a): # a=b
    print(a)


b = 1
b = [1, 2, 3]
b = True
b = 'abc'
b = {'1': 1}
b = fun
fun(b)

# 实参不管是什么类型的对象都可以

def fun2(a):
    # a = 10
    a[0] = 10
    print(a)

b = 1
b = [1, 2, 3]
c = b.copy()
fun2(c)
print(b)
运行相应结果
<function fun at 0x000002057F1FA8C8>
[10, 2, 3]
[1, 2, 3]

1-4-2.2 函数的传递方式
  • 定义形参时,可以为形参指定默认值。指定了默认值以后,如果用户传递了参数则默认值不会生效。如果用户没有传递,则默认值就会生效
  • 位置参数:位置参数就是将对应位置的实参赋值给对应位置的形参
  • 关键字参数 : 关键字参数可以不按照形参定义的顺序去传递,而根据参数名进行传递
  • 混合使用位置参数和关键字参数的时候必须将位置参数写到关键字参数前面去
def fun(a, b):  # 这个括号里叫做形参 也叫形式上参数
    # a = 1
    # b = 2
    print(a + b)


fun(1, 2)    # 此括号里为实参 实际参数 ,当你调用的时候传递实际参数
fun(1342434, 3453545)

位置参数
关键字参数

# c=0 给形参指定默认值,当没有传递实参的时候,使用默认值,当传递了参数,先使用传递来的参数
# def fun(a, b=0, c=0):
#     print(a)
#     print(b)
#     print(c)
#
# fun(1, 2)

# 函数的传递方式:
# 位置传参
# 关键字传参
def fun(a, b, c):
    print(a)
    print(b)
    print(c)

# fun(1, 2, 3) 位置传参
# fun(a=1, b=2, c=3)  # 关键字传参

# 位置传参和关键字传参混合使用,位置传参必须放天关键字传参的前面

# fun(a=1, b=2, 3)   # 报错原因 位置传参必须放天关键字传参的前面
# fun(1, 3, b=2)   # 报错原因 因为b同时进行了位置传参和关键字传参 传递参数太多报错
fun(3, b=1, c=2)   # 这个是正确的

相应运行结果:

3
1
2

可更改(mutable)与不可更改(immutable)对象

在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。

不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变 a
的值,相当于新生成了 a。

可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la
的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。

python 函数的参数传递:

不可变类型:类似 C++ 的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在
fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。

可变类型:类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响

python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。

python 传不可变对象实例

通过 id() 函数来查看内存地址变化:

def change(a):
    print(id(a))  # 指向的是同一个对象
    a = 10
    print(id(a))  # 一个新对象


a = 1
print(id(a))
change(a)
相应运行结果
1864461328
1864461328
1864461616

可以看见在调用函数前后,形参和实参指向的是同一个对象(对象 id 相同),在函数内部修改形参后,形参指向的是不同的 id。

传可变对象实例

可变对象在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了。例如:

def changeme(mylist):
    "修改传入的列表"
    mylist.append([1, 2, 3, 4])
    print("函数内取值: ", mylist)
    return


# 调用changeme函数
mylist = [10, 20, 30]
changeme(mylist)
print("函数外取值: ", mylist)

传入函数的和在末尾添加新内容的对象用的是同一个引用。故输出结果如下:
相应运行结果:
函数内取值:  [10, 20, 30, [1, 2, 3, 4]]
函数外取值:  [10, 20, 30, [1, 2, 3, 4]]

1-4-3 不定长参数
  • 定义函数时,可以在形参前面加一个*,这样这个形参可以获取到所有的实参,它会将所有的实参保存到一个元组中
  • 带*号的形参只能有一个,可以和其他参数配合使用
  • 形参只能接受位置参数,不能接受关键字参数
  • 形参可以接收其他的关键字参数,它会将这些参数统一保存到字典当中。字典的key就是参数的名字,字典的value就是参数的值
  • 形参只有一个,并且必须写在所有参数的后面
    不定长参数

你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。基本语法如下

def functionname([formal_args,] *var_args_tuple ):
   "函数_文档字符串"
   function_suite
   return [expression]

加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。

# 可写函数说明
def printinfo(arg1, *vartuple):
    "打印任何传入的参数"
    print("输出: ")
    print(arg1)
    print(vartuple)


# 调用printinfo 函数
printinfo(70, 60, 50)
相应运行结果
输出: 
70
(60, 50)

# 可写函数说明
def printinfo(arg1, *vartuple):
    "打印任何传入的参数"
    print("输出: ")
    print(arg1)
    for var in vartuple:
        print(var)
    return


# 调用printinfo 函数
printinfo(10)
printinfo(70, 60, 50)
相应运行结果
输出: 
10
输出: 
70
60
50

还有一种就是参数带两个星号 **基本语法如下:
加了两个星号 ** 的参数会以字典的形式导入

def functionname([formal_args,] **var_args_dict ):
   "函数_文档字符串"
   function_suite
   return [expression]
# 可写函数说明
def printinfo(arg1, **vardict):
    "打印任何传入的参数"
    print("输出: ")
    print(arg1)
    print(vardict)


# 调用printinfo 函数
printinfo(1, a=2, b=3)
相应运行结果
输出: 
1
{'a': 2, 'b': 3}

1-4-4. 参数的解包
  • 传递实参时,也可以在序列类型的参数前添加星号,这样它会自动的将序列中元素依次作为参数传递
  • 要求序列中的元素的个数必须和形参的个数一致

1-5

  • ①. 打印名片程序:输入姓名,电话号码,性别,最后打印出来名片
    • 控制姓名长度为6-20
    • 电话号码长度11
    • 性别只能允许输入男或女
    • 每一样信息不允许为空
while True:
    name = input('输入你姓名')
    iphone = input('输入你的电话号码')
    gender = input('输入你的性别')
    if name == '' or iphone == '' or gender == '':
        print('信息不能为空')
        continue
    else:
        print(name, iphone, gender)
        if  6 <= len(name) <= 20:
            print('你的姓名是%s:'%name )
            if  len(iphone) == 11:
                print('你的电话是%s:'%iphone)
                if gender not in "男女" or len(gender) != 1:
                    print('请输入有效的性别(男或女)')
                    continue
                else:
                    print('性别是%s:'%gender)

            else:
                print('你输入的不是有效号码')
                continue
        else:
            print('你输入的姓名不符合长度规定')
            continue
    break

    输出结果
    输入你姓名
输入你的电话号码158
输入你的性别ll
信息不能为空
输入你姓名sdsdffds
输入你的电话号码1589992
输入你的性别男
sdsdffds 1589992 男
你的姓名是sdsdffds:
你输入的不是有效号码
输入你姓名sdf
输入你的电话号码1559996223
输入你的性别男
sdf 1559996223 男
你输入的姓名不符合长度规定
输入你姓名sdfdfsdf
输入你的电话号码15878941234
输入你的性别ll
sdfdfsdf 15878941234 ll
你的姓名是sdfdfsdf:
你的电话是15878941234:
请输入有效的性别(男或女)
输入你姓名
    
  • ② 使用函数求前20个斐波那契数列斐波那契数列:1,1,2,3,5,8,13,21…即: 起始两项均为1,此后的项分别为前两项之和
def fun(n):
    a = 1
    b = 1
    c = 1
    while c <= n:
        if c == 1 or c == 2:
            print(c)
        else:
            a, b = b, b + a
            print(b)
        c += 1
fun(20)
相应运行结果
1
2
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765


  • ③ 编写一段代码,定义一个函数求1-100之间所有整数的和,并调用该函数打印出结果
def fun(a):
    for i in range(2, 100):  # 1-100之间 不应包括 1 和100
        a += i
        print(a)
b = 0
fun(b)
2
5
9
14
20
27
35
44
54
65
77
90
104
119
135
152
170
189
209
230
252
275
299
324
350
377
405
434
464
495
527
560
594
629
665
702
740
779
819
860
902
945
989
1034
1080
1127
1175
1224
1274
1325
1377
1430
1484
1539
1595
1652
1710
1769
1829
1890
1952
2015
2079
2144
2210
2277
2345
2414
2484
2555
2627
2700
2774
2849
2925
3002
3080
3159
3239
3320
3402
3485
3569
3654
3740
3827
3915
4004
4094
4185
4277
4370
4464
4559
4655
4752
4850
4949
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值