10.16day3:列表生成式、函数*args、random方法、随机点名表、递归函数及reduce求100和、高级函数map、reduce、filter、迭代生成器杨辉斐波、字符串int-float

一、== 列表生成式 ==

第一种
print([x for x in range(1,101)])     #前边的x是放在里面的x,这是for x in range(1,101)对所放x的描述,生成1~100

第二种
print([x if x%2==0 else -x for x in range(1,101)])   #对里面的奇数取负值,两个条件就放到for x in range(1,101)的前边

第三种
print([x for x in range(1,101) if x %2==0])    #选出里面的偶数,一个条件就可以放到for x in range(1,101)的后边

第四种
#用列表生成式把[[1,2],[3,4],[5,6]]变成[1, 2, 3, 4, 5, 6]
lists = [[1,2],[3,4],[5,6]]
data = [x for y in lists for x in y]   #需要两个变量,先遍历这个[[1,2],[3,4],[5,6]]大列表,
                                       # 遍历出的y就是这个[1,2]小列表,然后for x in y再遍历里面的小列表
                                       #然后把遍历到的y放到一个列表里面
print(data)

二、== 函数(实参、形参#*args:一个参数,**kwargs主要接键值对)==

fun(args,**kwargs)中的args,**kwargs什么意思?

*args和**kwargs主要用于函数定义。你可以将不定数量的参数传递给一个函数。
这里不定的意思是:预先并不知道,函数使用者会传递多少个参数给你,所以在这个
场景下使用这两个关键字。

1.*args是用来用来发送一个非键值对的可变数量的参数列表给一个函数
2.**kwargs允许你将不定长度的键值对,作为一个参数传递给一个函数

1)定义函数和函数调用
1.
def hi(ok):
    print(ok)
hi()   #结果:报错
hi('柳宗元')   #结果:柳宗元
print(hi('柳宗元') )  #结果:None,因为定义的函数没有返回值,我们给函数添加返回值

2.
def hi(ok):  #ok是形参
    print(ok)
    return 'yes'

print(hi('柳宗元') )  #结果:yes,定义了函数的返回值     #柳宗元是实参

3.可以返回多个值,并且以元组形式返回
def hi(ok):
    print(ok)
    return 'yes','i love you'

print(hi('柳宗元') )
#结果:
柳宗元
('yes', 'i love you')

4.#形参
def hello(hellos,ok=333,*args,**kwargs):
    print(ok,hellos,args,kwargs)
    return 123,456

5.# 实参
print(hello('你好','李白','我们一起喝酒',666,tel=1817892349,hello='world'))1)实参和形参都有的时候,实参的优先级高
def hi(ok='白居易'):
    print(ok)
    return 'yes','i love you'

print(hi('柳宗元') )
#结果:
柳宗元
('yes', 'i love you')2)有实参用实参,没有实参用形参
def hi(ok='白居易'):
    print(ok)
    return 'yes','i love you'

print(hi() )
#结果:
白居易
('yes', 'i love you')

6.*args,**kwargs这两个基本可以代替所有参数,
形参
def hello(hellos,ok=333,*args,**kwargs):
    print(ok,hellos,args,kwargs)
    return 123,456
# 实参
print(hello('你好','李白','我们一起喝酒',666,tel=1817892349,hello='world'))
#结果:
李白 你好 ('我们一起喝酒', 666) {'tel': 1817892349, 'hello': 'world'}   #'我们一起喝酒', 666这种单独的全都传给*args,返回值是('我们一起喝酒', 666)元组
(123, 456)    

*args:一个参数,**kwargs主要接键值对,一对一对的

三、random各种方法

import random
lists = [1,2,3,4,5,6,7,8,9]

1.random.shuffle(lists)

import random
lists = [1,2,3,4,5,6,7,8,9]
random.shuffle(lists) #打乱列表
print(lists)
结果:[3, 7, 5, 1, 6, 2, 9, 4, 8]

2.random.random()

import random
print(random.random())  #生成0~1之间的随机小数字
结果:0.019600727614542124

3.random.randrange(1,10)

import random
print(random.randrange(1,10))  #1~9里面随机取值,取得是整数
结果:2

4.random.sample(lists,4)

import random
lists = [1,2,3,4,5,6,7,8,9]
print(random.sample(lists,4))   #从lists里面随机取4个值,每次返回结果不一样
结果:[5, 6, 7, 9]

5.random.choice(lists)

import random
lists = [1,2,3,4,5,6,7,8,9]
print(random.choice(lists))    # #从lists里面随机取1个值,每次返回结果不一样
结果:4

6.random.randint(1,10)

import random
import time
print(random.randint(1,10))        #1~9里面随机取1个值,取得是整数
结果:10

四、== 随机点名表 ==

题目:定义一个函数,输入名字列表,输入随机数量,提取相应数量的名字,当次提取的名字不能有重复。
lists = ['admin{}'.format(x) for x in range(1,1000000)]
第一步、用列表生成式99个名字
lists = ['admin{}'.format(x) for x in range(1,100)]  #用列表生成式99个名字
print(lists)
第二步、定义函数

1.第一种random.shuffle(m)
import random
lists = ['admin{}'.format(x) for x in range(1,100)]  #用列表生成式99个名字
print(lists)
def get_random_name(m,num):    #num随机取几个名字
    random.shuffle(m)
    if len(m)>=num:            #把里面顺序打乱就可以取值了,先判断里面的数量
        return m[:num]         #返回整成的值,从开头取到随机num
    else:
        return '名字数量不足!'
print(get_random_name(lists,1000))  #随便叫什么都行,实际上是把lists传给m

2.第二种random.choice(m)

import random
lists = ['admin{}'.format(x) for x in range(1,100)]  #用列表生成式99个名字
print(lists)
def get_random_name(m,num):
    if len(m) >= num:
        lists = []
        for i in range(num):
            lists.append(random.choice(m))
        return lists
    else:
        return '名字数量不足!'

print(get_random_name(lists,5))

#出现的问题:这个办法会取到重复的值,该怎么办?

步骤
1.random.choice(lists)
2.定义一个空列表,lists = []
3.渠道的值用空列表装一下lists.append(random.choice(lists))
4.要几个值就循环几次、for i in range(num):
5.最后返回一个return lists
6.choice里面应该写m,lists.append(random.choice(m))
7.print(get_random_name(lists,10))
8.当然判断也可以粘贴过来用 if len(m) >= num:
else:
        return '名字数量不足!'

#出现的问题:这个办法会取到重复的值,该怎么办?
方案:把lists = []变成集合lists = set([]),因为集合会自动给去掉重复的值。
然后把把lists.append(random.choice(m))变成lists.add(random.choice(m))

import random
lists = ['admin{}'.format(x) for x in range(1,100)]  #用列表生成式99个名字
print(lists)
def get_random_name(m,num):
    if len(m) >= num:
        lists = set([])
        for i in range(num):
            lists.add(random.choice(m))
        return lists
    else:
        return '名字数量不足!'

#print(get_random_name(lists,5))
print(get_random_name(lists,5),len(get_random_name(lists,20)))

#再统计一下集合里面取的值的长度,len(get_random_name(lists,5))
#出现问题,{'admin62', 'admin68', 'admin10', 'admin35', 'admin60'} 17,取得值不够20个。
#原因:往里面确实添加了20个值,但是集合自动去重,所以留到里面的会减少
#解决方案:不是要20个值嘛,
1.那就写一个死循环,while True:
2.什么时候停呢?那就写一个判断,判断这个几个,存够20个值,就跳出这个循环
#     if len(m) == num:
#         lists = set([])
#            break


import random
lists = ['admin{}'.format(x) for x in range(1,100)]  #用列表生成式99个名字
print(lists)
def get_random_name(m,num):
    if len(m) >= num:
        lists = set([])
        while True:
            if len(lists)==num:
                break
            lists.add(random.choice(m))
        return lists
    else:
        return '名字数量不足!'

print(get_random_name(lists,20),len(get_random_name(lists,20)))  #随便叫什么都行,实际上是把lists传给m
问题:计算量变大,把名字变成for x in range(1,10000)]  #用列表生成式10000个名字,时间就会很长
写一个计算时间的函数,我们需要引用一个新的包,import time
程序开始之前先记录一个开始的时间戳
begin = time.time()
print(get_random_name(lists,90000),len(get_random_name(lists,90000)))
stop = time.time()
print(stop-begin)

显示时间是:0.43766021728515625s

思路:重复的名字一直在集合里面,可以把重复的弹出去,等下一次进来的时候就不会重复了。
1.先写核心,判断等会再加
2.把里面的删除remove

import random
lists = ['admin{}'.format(x) for x in range(1,100)]  #用列表生成式99个名字
print(lists)
def get_random_name(m,num):
    if len(m) >= num:
        lists = []
        for i in range(num):
            data = random.choice(m)
            lists.append(data)
            m.remove(data)  #数字大了很慢
        return lists
    else:
        return '名字数量不足'

print(get_random_name(lists,20),len(get_random_name(lists,20)))  #随便叫什么都行,实际上是把lists传给m
数字大了很慢,换random.randrange(m)试一试

3.第三种random.randrange(m)
import random
lists = ['admin{}'.format(x) for x in range(1,100)]  #用列表生成式99个名字
print(lists)
def get_random_name(m,num):
    if len(m) >= num:
        lists = set([])
        while True:
            if len(lists) == num:
                break
            data = random.randrange(len(m))
            #m.pop(data)
            lists.add(m.pop(data))
            # data = random.choice(m)
            # lists.add(data)
            # m.remove(data)
        return lists
    else:
        return '名字数量不足'

print(get_random_name(lists,10))  #随便叫什么都行,实际上是把lists传给m


print(get_random_name(lists,20),len(get_random_name(lists,20)))
begin = time.time()
print(get_random_name(lists,900000),len(get_random_name(lists,900000)))
stop = time.time()
print(stop-begin)

测试的时间结果:
0.43766021728515625
4.4  9000000第二种方法random.choice(m)
1.6  9000000第一种方法random.shuffle(m)
s
主要是列表结构和字典结构的问题,差的很多,随机数的数量并没有这个导致的问题大,
random.shuffle(m)>random.choice(m)>random.randrange(m)

五、== 递归函数求0~100奇数偶数和 ==

1.1~100的和

def get_data(n):
    if n==1:
        return 1
    else:
        return n+get_data(n-1) #100、99、98....1

print(get_data(100))

结果:5050

2.1~100偶数的和

def get_data(n):
    if n%2==1:   #可以把99处理成偶数,奇数的话就减1
        n = n-1
    if n==0:
        return 0
    else:
        return n+get_data(n-2)

print(get_data(99))
结果:2450
print(sum(range(2,99,2)))
结果:2450

六、高级函数:map、reduce、filter

1.求列表里面每个值的平方map

def get_data(x):
    return x**2
lists = [2,3,4]
print(list(map(get_data,lists)))
#结果:[4, 9, 16]

2.reduce(累加的方法)可以联想到斐波那契数列

(1)== reduce求1~100的和 ==

1.reduce(累加的方法)

lists = [2,3,4]
print(lists)
def data_add(x,y):
    return x+y
from functools import reduce
last = reduce(data_add,lists)
print(last)
结果:9
x   y     x     y
2   3     5     4      9

2.reduce1~100的和

lists = [x for x in range(101)]
print(lists)
def data_add(x,y):
    return x+y
from functools import reduce
last = reduce(data_add,lists)
print(last)
结果:5050


from functools import reduce
print(reduce(lambda x,y:x+y,range(101)))
结果:5050

七、把字符串数字转成整型数字,实现int功能,可以用map()函数和reduce()函数

strs = '18514203544'
print(int(strs),type(int(strs)))

方法一

#方法一
from functools import reduce
strs = '18514203544'
def get_num(n):
    dicts = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
    return dicts[n]

def get_result(x,y):
    return x*10+y

def int1(strs):
    data = list(map(get_num,strs))
    result = reduce(get_result,data)
    return result

print(int1(strs))
结果:18514203544
1851
1*10+8=18
18*10+5=185
185*10+1=1851

方法二

strs = '18514203544'
print(int(strs),type(int(strs)))
from functools import reduce
def char_to_number(string):
    all_number_dict={'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
    #以参数string为键,取出all_number_dict里面的值
    return all_number_dict[string]

def result_number(x,y):
    res = x*10+y
    return res

res=list(map(char_to_number,'123'))
print(res)

result=reduce(result_number,res)
print('最终的结果是:',result,'最终的类型',type(result))

八、把字符串数字转成浮点型数字,实现float功能,可以用map()函数和reduce()函数

方法一

from functools import reduce
def get_num(n):
    dicts = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
    return dicts[n]

def get_result(x,y):
    return x*10+y

def float1(strs):
    data = list(map(get_num,strs))
    result = reduce(get_result,data)
    return result

from decimal import Decimal    #Decimal可以精确计算

strs = '1234.890'
data = strs.replace('.','')
dian_index = strs.find('.')
chazhi = 10**(len(data)-dian_index)
print(Decimal(float1(data))/chazhi)
结果:1234.89

方法二

根据小数点把浮点数分成两半分别计算
from functools import reduce
from decimal import Decimal     #使结果更加精准

def get_num(n):
    dicts = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
    return dicts[n]

def get_result(x,y):
    return x*10+y

def float1(strs):
    data = list(map(get_num, strs))
    result = reduce(get_result, data)
    return result


dicts = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
strs = '183243242.3545645654654'
i = strs.split('.')[0]       #根据小数点把浮点数分成两半分别计算
f = strs.split('.')[1]
print(i,f)
def get_data(x,y):
    return x*0.1+y
last = reduce(get_data,map(get_num,f[::-1]))
print(float1(i)+Decimal(last)/10)

结果:
183243242 3545645654654
183243242.3545645654653999834

分析
# 4564565465453
# 5.4
# 5.3
# 4.53

九、杨辉三角

[1]
[1,1]
[1,2,1]
[1,3,3,1]
[1,4,6,4,1]
计算杨辉三角 补0法
lists = [1]
for i in range(9):
    print(lists)   #打印出最开始的[1]
    n = []
    for i in range(len(lists)-1):
        n.append(lists[i]+lists[i+1])
    lists = [1]+n+[1] #拼接左右两边的[1]

十、迭代器、生成器、可迭代对象:基础知识

可迭代对象:所有能被for循环遍历的。如:range(100),{1,2,3,4}
迭代器:能被next函数不断调用,并不断返回下一个值。listset、dicts通过iter()转换的
生成器:是一种特殊的迭代器,只有列表生成式和函数yield返回生成的才是生成器

1迭代器iterator

a = range(100)
print(next(a))   #报错,这个不是迭代器

这个是迭代器,像我们以前学过的列表生成式
a = (x for x in range(5))
print(next(a))   #结果:0
print(next(a))   #结果:1
print(next(a))   #结果:2
print(next(a))   #结果:3
print(next(a))   #结果:4

2生成器generator

定义生成器的方法
方法一
a = (x for x in range(10))

方法二
def hello():
    for i in range(5):
        yield i

a = hello()
print(next(a))   #结果:0
print(next(a))   #结果:1
print(next(a))   #结果:2
print(next(a))   #结果:3
print(next(a))   #结果:4

3是可迭代对象,但不是迭代器的

lists = [1,2,3,4,5]
# for i in lists:
#     print(i)
next(lists)
结果出错:TypeError: 'list' object is not an iterator

4我们可以用iter函数把list、set、dicts通过iter()转换的这种是可迭代对象,但不是迭代器的转成迭代器

lists = iter([1,2,3,4,5])

print(next(lists))   #结果:1
print(next(lists))   #结果:2
print(next(lists))   #结果:3
print(next(lists))   #结果:4
print(lists)         #结果:<list_iterator object at 0x000001B8FAA8D1E0>

但是这个不是生成器,因为不是方法一和方法二生成的。
生成器的优点:1。比较省内存。缺点:1.以消耗CPU资源换更大的内存空间
yieldreturn一样可以返回值,但是yield会进行存档。

十一、杨辉三角迭代器

def hello(m):
    lists = [1]
    for i in range(m):
        yield lists
        n = []
        for i in range(len(lists)-1):
            n.append(lists[i]+lists[i+1])
        lists = [1]+n+[1]

for i in hello(20):
    print(i)

十二、斐波那契数列迭代器

def hello(m):
    x1 = 0
    yield x1
    y1 = 1
    yield y1
    for i in range(m):
        x1,y1 = y1,x1+y1
        yield y1
for i in hello(10):
    print(i)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ゆきな

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值