‘’’
互送礼活动
圣诞节到了,公司开展一个互送礼物活动。每个员工系统会随机抽取一位送礼物的对
象,送礼对象不能重复。最终每个人都能送出和收到一份礼物。
·定义好公司员工名单
·循环系统会随机抽取一位收礼物的人
·打印最终的送礼和收礼的关系
‘’’
除了循环之外,还可以用什么方式
send_lst = ['员工a','员工b','员工c','员工d','员工e','员工f']
get_lst = send_lst[:] #(注:列表的拷贝)
for i in send_lst:
flag = 0 # 标志位
if i in get_lst:
flag = 1
get_lst.remove(i)
get = random.choice(get_lst)
get_lst.remove(get)
if flag == 1:
get_lst.append(i)
print(f"{i}-->{get}")
import random
students = {
'a','b','c','d','e','f','g'}
students1 = list(students)
students2 = list(students)
for i in range(len(students)):
num1 = random.randint(0, len(students1)-1)
num2 = random.randint(0, len(students2)-1)
send_people = students1[num1]
students1.pop(num1)
receive_people = students2[num2]
students2.pop(num2)
print(f"{send_people}送礼物给{receive_people}")
(注:bug自己送给自己的情况)
from random import choice
send_lst = ['员工a','员工b','员工c','员工d','员工e','员工f']
get_lst = ['员工a','员工b','员工c','员工d','员工e','员工f']
for i in send_lst:
while True:
j = choice(get_lst)
if i != j:
get_lst.remove(j)
print(f"送礼:{i} --> 收礼:{j}")
break
elif i == j == send_lst[-1]:
print("这题不会")
break
else:
continue
(注:做个判断:列表长度为2时,且f在get_lst 里面,避免f送给自己。判断一下送礼的人是倒数第2个,且f还在get_lst里面)
(注:可以取一个集合。还剩2个人的时候,把list转换成set,取交集)
(注:查看两个列表里 是否有 相同元素。转换成set集合,取交集)
import random
name1=["wang","peng","tang","feng","zhang","xu","li","liang","wen"]
name2=[]
random.shuffle(name1) #(注:随机打乱)(注:会改变nam1本身)
name2=name1[::-1] #(注:倒序)
#tup=[]
while name1: #(注:name1不为空时循环)
first=name1.pop() #(注:送礼的人。删除最后一个人)
second=name2.pop() #(注:收礼的人。循环)
if first==second:
name1.insert(0,first)
name2.append(second)
else:
print("送礼人:", first, end=" ")
print("收礼人为:", second)
a = [1,2,3,4,5,6,7]
b = [7,6,5,4,3,2,1]
>>> import random
>>> name = [1,2,3,4]
>>> random.shuffle(name) #(注:name本身 改变)
>>> name
[4, 2, 1, 3]
>>> import random
>>> a = ["a","b","c","d","e"]
>>> random.shuffle(a)
>>> a
['e', 'b', 'c', 'a', 'd']
为什么没有拉下来?碰到有冲突内容。
vim .idea/lgj.iml
进入冲突文件 去编写它
<<<<< HEAD
手动修改
删掉之后,选择其一order
>>> a = [1,2,3]
>>> b = a
>>> id(a)
140357548964872 #(注:指向同一内存地址)
>>> id(b)
140357548964872 #(注:指向同一内存地址)
>>> a = [3,4,5]
>>> b = a
>>> b[1] = 6 #(注:a的元素也发生变化)
>>> a
[3, 6, 5]
>>> b = a[:] #(注:列表的拷贝)
>>> id(a)
140357548968136
>>> id(b)
140357548967816
for i in send_lst:
flag = 0 # 标志位 p判定i
if i in get_lst:
flag = 1
get_lst.remove(i)
get = random.choice(get_lst)
get_lst.remove(get)
if flag == 1:
get_lst.append(i)
print(f"{i}-->{get}")
# 1、回文
str = input("请输入:")
if str == str[::-1]:
print("输入为回文")
else:
print("输入非回文")
#2、找出出现次数过半元素
lst = list(input("请输入:"))
for index, value in enumerate(lst):
if lst.count(value) > len(lst) / 2:
print(f"列表中出现次数过半的元素是{value}")
break
elif index == len(lst)//2:
print("没有出现次数过半的元素")
print('==找出列表中出现次数过半的元素==')
my_str = input('请输入列表中的元素,用空格分开:')
my_list = my_str.split()
print(f'列表为{my_list}')
my_set = set(my_list)
for item in my_set:
if my_str.count(item)/len(my_list) > 0.5:
print(f'列表元素{item}出现过半')
break
else:
print('没有出现次数过半的元素')
# 3、输出最小回文
input_lst = list(input("请输入:"))
two_lst = [input_lst, input_lst[::-1]]
for lst in two_lst:
for index, value in enumerate(lst):
if lst != lst[::-1]:
if index == 0:
lst.append(value)
else:
lst.insert(-index,value)
if len(two_lst[0]) < len(two_lst[1]) or two_lst[0] == two_lst[1]:
print(f"最小回文:{two_lst[0]}")
elif len(two_lst[0]) > len(two_lst[1]):
print(f"最小回文:{two_lst[1]}")
else:
print(f"最小回文:{two_lst[0]};{two_lst[1]}")
a = input("请输入:")
b = list(a)
c = b[::-1]
for i in range(len(b)) :
d = b[0:(len(b)-i)]
e = c[0:]
if d == d[::-1] :
g = c[0:i]
f = g + b
print(f"最小回文是:{f}")
break
s = "abc"
m = 0
res = s[::-1] # cba
while s[m:len(s)] != res[0:len(res)-m] and m < len(s):
m+=1
print(s+res[len(s) -m])
什么是函数
·数学函数:f(x) = x+10
·开发语言:函数是指实现某个功能的一段代码
使用函数的好处
·模块化程序设计
·减少代码冗余
·维护方便
函数的定义
·函数是编程是最基本的魔法,同时,一切复杂又被隐藏其中
·缩进的部分被称为语句块,表示语句和逻辑的从属关系。
·def和return是关键字
def func01():
print("this is function 01")
func01()
func01()
func01()
func01()
注:return是函数的返回值
def bmi(s, w): # 定义函数,函数名与内容相关 # 形参(定义的参数名)
bmi = w / s**2
return bmi # 函数返回值
bl = bmi(181, 115) # 实参
print(bl)
注:不接返回值,默认返回值为None,为假
什么是函数参数
·函数取得的参数是你提供给函数的值。
·这些参数就像变量一样,只不过它们的值是在我们调用函数的时候定义的
参数的形式
·参数在函数定义的圆括号对内指定,用逗号分割。
·形参:函数中的参数名称为形参
·实参:提供给函数调用的值称为实参
参数分类 (按定义)
·必选参数(位置参数) => 在调用时必须要填
·默认参数(关键字参数) => 提供默认值,调用时可填可不填
·可变位置参数
·可变长关键字参数
参数分类 (按调用)
·位置参数(必选参数) => 按参数顺序依次传递
·关键字参数(默认参数) => 按key依次传递
注:注意使用顺序
def bmi(s, w): # 定义函数,函数名与内容相关
bmi = w / s**2
s = s+10
return bmi # 函数返回值
s = 1.58
w = 45
bl = bmi(s, w)
print(bl)
print(s)
18.02595737862522
1.58
注:函数体内定义的是 局部变量
# 位置参数
def funcsum(a,b): # 位置一一对应
return a+b
funcsum(1,2) # 位置一一对应
def func02(name, age, sex):
print(f"my name is {name}, age is {age}, sex is {sex}")
func02("chenpeng", 18, "m")
注:传2个参数会报错。定义几个参数,就得传几个参数
# 默认参数/关键字参数
def func03(name, age, sex="f"): # 定义的时候,直接给他一个默认值
print(f"my name is {name}, age is {age}, sex is {sex}")
func03("chenpeng", 18) # 不传的话,默认参数 sex="f"
func03("chenpeng", 18, "male")
·对于实参而言,位置参数要放在关键字参数的前面
func03(“chenpeng”, age=18, sex=“male”) # 这样写,"参数="必须放在位置参数后面
·如果都是用关键字参数传递值,那关键字参数的顺序是可以打乱的
func03(sex=“testm”,name=“wenyao”,age=20) # 位置可以打乱
#不用等于号,仅仅是位置参数的传递,需要一一对应
# 关键字参数的定义,要放在位置参数的后面
def func03(name = "chenpeng", age, sex): (注:报错)
print(f"my name is {name}, age is {age}, sex is {sex}")
SyntaxError: non-default argument follows default argument
# *num 涉及到packing and unpacking的操纵 (包装;解包装)
# packing
# 1,2 ==> 元组 {1,2}
# *num --> unpacking --> 1 2 3 4
# a = {1,2,3,4} --> 1,2,3,4 (注:元组)
# a = {"test1":1, "test2":2} --> test1 = 1 , test2 = 2 # 位置一一对应
# 可变位置参数
def myargs(*num):
print(type(num), num)
def myargs2(num):
print(type(num), num)
myargs()
myargs(1,2)
myargs(1,2,3)
myargs(1,2,3,4) # 长度不固定
myargs2((1, 2))
myargs2((1, 2, 3))
myargs2((1, 2, 3, 4))
def myargs(*num):
print(type(num), num)
print(*num) (注:打印 解包装)
myargs()
myargs(1, 2)
myargs(1, 2, 3)
1 2 (注:打印 解包装)
1 2 3
可变长关键字参数
#可变长关键字参数
#packing --> a=1,b=2 --> packing --> 字典 {“a”:1,“b”:2}
#unpacking --> a=1,b=2,c=3
def myargs2(**num):
sum = 0
for i in num.values():
sum += i
print(sum)
myargs2(a=1,b=2,c=3,d=1)
myargs2(a=2,b=3)
return语句的作用
·return语句用来退出函数
函数只要遇到return就结束执行
·返回一些数据
函数中return语句的数量
·可以有0,1或多个return语句
·最终根据代码逻辑,执行第一个遇到return
·如果代码执行到return语句,函数默认返回None
示例:
·return 退出函数,并且可以返回结果
·一旦执行到return,就退出,后面语句不会执行
·如果没有return的话,默认返回None。如果return后面不接任何表达式,也是返回None
·return 可以返回多个值
# 函数的return语句
def maxnum_test(x,y):
print("return语句......")
if x > y:
print("return x")
return x
else:
print("return y")
return y
print("return语句 end") (注:这条没有执行)
maxnum_test(2,3)
return语句…
return y
# 函数的return语句
def maxnum_test(x,y):
print("return语句......")
if x > y:
print("return x")
return x
else:
print("return y")
return #(注:return后面不接任何表达式,也是返回None)
print("return语句 end")
t1 = maxnum_test(2,3)
print(t1)
return语句…
return y
None (注:返回None)
# 函数的return语句
def maxnum_test(x,y):
print("return语句......")
if x > y:
print("return x")
return x,y
else:
print("return y")
return
print("return语句 end")
t1 = maxnum_test(2,3)
print(t1) #(注:语句2 return后面没有返回值,默认返回None)
t2 = maxnum_test(4,3)
print(t2) #(注:t2 1个参数,返回的是元组(x,y) (4,3))
t3, t4 = maxnum_test(4,3) #(注:t3 t4 2个参数,返回的是 x,y 4,3)
print(t3)
print(t4)
return语句…
return y
None (注:返回None)
return语句…
return x
(4, 3) (注:返回(4, 3))
return语句…
return x (注:返回4, 3)
4
3
匿名函数及其定义
·匿名函数在创建时不需要命名,所以叫匿名函数
·匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果
匿名函数
不需要创建函数名
只能有一个表达式,不用写return,该表达式的结果就是返回值
定义规则
lambda args1,args2 : args1 + args2
add2 = lambda a,b : a+b
print(add2(2,3))
def add(a,b):
return a+b
print(add(2,3))
comp = lambda x,y: x if x>y else y
print(comp(3,4)) #(注:返回y)
print(comp(46,3)) #(注:返回x)
4
46
什么时候使用匿名函数
·当函数只是实现非常简单并且一次性使用时,可以定义为匿名函数
·当我们在传入函数时,不需要显式地定义函数,直接传入匿名函数更方便。
把匿名函数作为返回值返回
求n! => 123…*n
建议:如果可以用普通函数解决的,尽量不要用递归(数据存放到堆栈 中,递归次数多,会导致内存的消耗比较大)
def factorial_func(n):
factor_num = 1
for i in range(1,n+1):
factor_num *= i
return factor_num
print(factorial_func(4))
24
自己调用自己,形成1个循环
def factotial_func2(n):
if n == 1: #(注:递归的出口条件)
return 1 #(注:跳出递归的循环后,再去执行它。往上计算)
return n * factotial_func2(n-1)
print(factotial_func2(4))
24
什么是递归
·递归(英语:Recursion),又译为递回
·在数学与计算机科学中,是指在函数的定义中使用函数自身的方法。
·递归是把问题分解成为规模更小的、具有与原问题有着相同解法的问题。 比如二分查找算法,1到10的累加
实现递归的条件
·出口条件,即递归“什么时候结束”,这个通常在递归函数的开始就写好
·可以通过递归调用来缩小问题规模,且新问题与原问题有着相同的形式。
注:尽量避免使用递归,除非没有更好的算法或者某种特定情况下使用
每次递归都会保存在内存中,非常占用内存,并且效率低
Python中默认递归深度为999
def factotial_func2(n):
if n == 1:
return 1
return n * factotial_func2(n-1)
print(factotial_func2(4))
print(factotial_func2(998)) #(注:Python中默认递归深度为999)
函数的参数传递 本质上是传递参数的引用
·传递不可变对象
·参数x是一个新的引用,指向a所指的对象。
·如果参数是不可变(immutable)的对象,a和x引用之间相互独立。对参数x的操作不会影响引用a。
·这样的传递类似于C语言中的值传递。
·传递可变对象
·如果传递的是可变(mutable)的对象,那么改变函数参数,有可能改变原对象。
·所有指向原对象的引用都会受影响,编程的时候要对此问题留心。
·传递可变对象
·在定义参数时,尽量避免参数的默认值设置成一个可变对象
# 本质是传递引用
# 传递不可变数据类型
def f(x):
x = 100 #(注:传递不可变数据类型)
print(x)
x=1
f(x)
print(x)
100
1
形参和实参本质上不是同一个变量
# 传递可变数据类型
def f(x):
x[0] = 100 #(注:传递可变数据类型)
print(x)
a = [1,2,3]
f(a)
print(a)
[100, 2, 3]
[100, 2, 3]
# 参数定义时,尽量避免定义成一个可变对象
def f(a=[]):
a.append(1) #(注:会影响后面的额调用)
print(a)
f()
f()
f()
[1]
[1, 1]
[1, 1, 1]
def f(b):
b["test"] = 1 #(注:字典是可变类型,指向同一个对象。列表、字典、集合 是可变类型)
print(b)
b = {
"test":2,"test2":3}
f(b)
print(b)
{‘test’: 1, ‘test2’: 3}
{‘test’: 1, ‘test2’: 3}
>>> a = {
"a","b","c"}
>>> type(a)
<class 'set'>
>>> id(a)
139978717766152
>>> a.add("d")
>>> a
{
'c', 'b', 'a', 'd'}
>>> id(a)
139978717766152
变量作用域:变量起作用的范围
所有变量的作用域是它们被定义的块,从它们的名称被定义的那点开始。
变量的分类
·局部变量:相对于函数来说,它是局部的,在函数体内使用
·全局变量:全局的,可以在函数体外使用。函数内部定义全局变量,global
·内建变量
# 使用global关键字变成一个全局变量
def f():
global x
x = 5
x = 1
f()
print(x)
5
LEGB原则
LEGB作用域查找原则,当引用一个变量时,python按照以下顺序依次进行查找:
1、从本地变量中 -> Local(function)函数内部
2、在任意上层函数的作用域 -> Enclosing function locals 嵌套函数内部
3、在全局作用域 -> Global(module)
4、最后在内置作用域中查找 -> Built-in(python)
第一个能够完成查找的就算成功。
变量在代码中被赋值的位置通常就决定了它的作用域。
如果都没有找到,就会报错
# 变量名解析:LEGB原则
def f(x):
def f2():
x = 3
print(x)
f2() # 定义了函数,需要使用它
x = 2
f(x)
3
def f(x):
def f2():
#x = 3
print(x)
f2() # 定义了函数,需要使用它
x = 2
f(x)
2
def f(x):
x = 4
def f2():
#x = 3
print(x)
f2() # 定义了函数,需要使用它
x = 2
f(x)
4
def f(x):
#x = 4
def f2():
#x = 3
print(x)
f2() # 定义了函数,需要使用它
x = 2
f(x)
2
def f(x):
#x = 4
def f2():
#x = 3
print(x)
f2() # 定义了函数,需要使用它
#x = 2
f(x)
NameError: name ‘x’ is not defined
def f(x):
#x = 4
def f2():
#x = 3
x.append("4") #(注:可变数据类型可以修改)
print(x)
f2() # 定义了函数,需要使用它
x = [1,2,3]
f(x)
print(x)
[1, 2, 3, ‘4’]
[1, 2, 3, ‘4’]
注释分类
·单行注释
·多行注释
·特殊注释
#!/usr/bin/env python
Python告诉LINUX 去哪个路径下找Python的翻译器
#--coding:utf-8--
告诉Python解释器,如何解释字符串中的编码类型
文档注释
·文档字符串是包、模块、类或函数里的第一个用引三号引起来的字符串
·这些字符串可以通过对象的 __doc__成员被自动提取,并且被pydoc所用。
第一个三引号注释,会被help所识别
·函数是大家的函数,方法是类的方法
·与类和实例无绑定关系的function都属于函数(function)
·与类和实例有绑定关系的function都属于方法(method)
print是函数,可以直接调用
a.add(“f”) 是属于a的1种属性,是1种方法
内建:Python已经建好的,我们无需导入,直接调用就好。
·内建函数:Python已经建好的函数
·内建方法:一般是针对面向对象而言,是类的方法。
内建方法就是指一个自带的对象所带的方法。如list的的pop操作
所谓工厂函数就是指这些内建函数都是类对象
·它们看上去象函数, 实质上他们是类。
·当你调用它们时, 实际上是生成了该类型的一个实例, 就象工厂生产货物一样。
·int(), float(), complex(), bool()
·str(), bytes() : 字符型
·list(), tuple():生成列表或者元组
·dict(), set():生成一个字典或集合
·slice():切片
注:以上都属于工厂函数
builtins有哪些
>>> help(__builtins__)
·内建异常
·内建变量
·工厂函数
·内建函数
·input()、print():输入输出函数
·oct()、hex():转换函数
·chr()、ord():ASCII与字符转换
·abs(num)、pow()、round():数值运算函数
·isinstance():判断是不是实例
·id():求内存地址
·len():求长度
·sum():求和
·max():最大值
·min():最小值
·enumerate(iter) :接受一个可迭代对象作为参数,返回一个enumerate 对象
如果你想要为一个定义在函数外的变量赋值,在函数里使用global语句
·使用global语句可以清楚地表明变量是在外面的块定义的。
·global语句被用来声明变量是全局的
如果一定要在全局范围内使用函数内的变量,可在定义时,声明成global
python使用命名空间记录变量。python中的命名空间就像是一个dict,key是变量的名字,value是 变量的值。
·local namespace: 每个函数都有一个自己的命名空间,它记录了函数的变量。
·global namespace: 每个module有一个自己的命名空间,它记录了module的变量,functions, classes 和其它imported modules,还有 module级别的 变量和常量。
·build-in namespace: 可以被任意模块访问,它包含了build-in function 和 exceptions。
可变长位置参数 (*args)
·计算N个数的和(N数量不确定)
·计算N个数的和
·N数量不确定
·最佳方式:mysun(必选参数, *args, 默认参数, **kargs)
·不是每项都需要,如果需要的话,要按上述顺序
·mysum(位置参数,关键字参数)