Python基础学习笔记-9.原理与拓展

9.原理与拓展

9.1.数据类型的底层实现

9.1.1.列表的实现

1、错综复杂的复制

list_1 = [1, [22, 33, 44], (5, 6, 7), {"name": "Sarah"}]

浅拷贝

# list_3 = list_1          # 错误!!!

list_2 = list_1.copy()     # 或者list_1[:] \ list(list_1) 均可实习浅拷贝

对浅拷贝前后两列表分别进行操作

list_2[1].append(55)

print("list_1:  ", list_1)

print("list_2:  ", list_2)

list_1:   [1, [22, 33, 44, 55], (5, 6, 7), {'name': 'Sarah'}]

list_2:   [1, [22, 33, 44, 55], (5, 6, 7), {'name': 'Sarah'}]

2、列表的底层实现

引用数组的概念

列表内的元素可以分散的存储在内存中

列表存储的,实际上是这些元素的地址!!!——地址的存储在内存中是连续的

list_1 = [1, [22, 33, 44], (5, 6, 7), {"name": "Sarah"}]

list_2 = list(list_1)   # 浅拷贝   与list_1.copy()功能一样

(1)新增元素

list_1.append(100)

list_2.append("n")

print("list_1:  ", list_1)

print("list_2:  ", list_2)

list_1:   [1, [22, 33, 44], (5, 6, 7), {'name': 'Sarah'}, 100]

list_2:   [1, [22, 33, 44], (5, 6, 7), {'name': 'Sarah'}, 'n']

(2)修改元素

list_1[0] = 10

list_2[0] = 20

print("list_1:  ", list_1)

print("list_2:  ", list_2)

list_1:   [10, [22, 33, 44], (5, 6, 7), {'name': 'Sarah'}, 100]

list_2:   [20, [22, 33, 44], (5, 6, 7), {'name': 'Sarah'}, 'n']

(3)对列表型元素进行操作

list_1[1].remove(44)

list_2[1] += [55, 66]

print("list_1:  ", list_1)

print("list_2:  ", list_2)

list_1:   [10, [22, 33, 55, 66], (5, 6, 7), {'name': 'Sarah'}, 100]

list_2:   [20, [22, 33, 55, 66], (5, 6, 7), {'name': 'Sarah'}, 'n']

(4)对元组型元素进行操作

list_2[2] += (8,9)

print("list_1:  ", list_1)

print("list_2:  ", list_2)

list_1:   [10, [22, 33, 55, 66], (5, 6, 7), {'name': 'Sarah'}, 100]

list_2:   [20, [22, 33, 55, 66], (5, 6, 7, 8, 9), {'name': 'Sarah'}, 'n']

(5)对字典型元素进行操作

list_1[-2]["age"] = 18

print("list_1:  ", list_1)

print("list_2:  ", list_2)

list_1:   [10, [22, 33, 55, 66], (5, 6, 7), {'name': 'Sarah', 'age': 18}, 100]

list_2:   [20, [22, 33, 55, 66], (5, 6, 7, 8, 9), {'name': 'Sarah', 'age': 18}, 'n']

3、深拷贝

浅拷贝之后

针对不可变元素(数字、字符串、元组)的操作,都各自生效了

针对可变元素(列表、集合)的操作,发生了一些混淆

引入深拷贝

深拷贝将所有层级的相关元素全部复制,完全分开,泾渭分明,避免了上述问题

import copy

list_1 = [1, [22, 33, 44], (5, 6, 7), {"name": "Sarah"}]

list_2 = copy.deepcopy(list_1)

list_1[-1]["age"] = 18

list_2[1].append(55)

print("list_1:  ", list_1)

print("list_2:  ", list_2)

list_1:   [1, [22, 33, 44], (5, 6, 7), {'name': 'Sarah', 'age': 18}]

list_2:   [1, [22, 33, 44, 55], (5, 6, 7), {'name': 'Sarah'}]

9.1.2.字典的实现

1、查找非常快

import time

ls_1 = list(range(1000000))

ls_2 = list(range(500))+[-10]*500

start = time.time()

count = 0

for n in ls_2:

    if n in ls_1:

        count += 1

end = time.time()

print("查找{}个元素,在ls_1列表中的有{}个,共用时{}秒".format(len(ls_2), count,round((end-start),2)))

查找1000个元素,在ls_1列表中的有500个,共用时6.19秒

import time

d = {i:i for i in range(1000000)}

ls_2 = list(range(500))+[-10]*500

start = time.time()

count = 0

for n in ls_2:

    try:

        d[n]

    except:

        pass

    else:

        count += 1

end = time.time()

print("查找{}个元素,在ls_1列表中的有{}个,共用时{}秒".format(len(ls_2), count,round(end-start)))

查找1000个元素,在ls_1列表中的有500个,共用时0秒

2、字典的底层实现

通过稀疏数组来实现值的存储与访问

字典的创建过程

第一步:创建一个散列表(稀疏数组 N >> n)

通过hash()计算键的散列值

d = {}

print(hash("python"))

print(hash(1024))

print(hash((1,2)))

-4771046564460599764

1024

3713081631934410656

893833775213427022

d["age"] = 18    # 增加键值对的操作,首先会计算键的散列值hash("age")print(hash("age"))

893833775213427022

第二步:根据计算的散列值确定其在散列表中的位置

极个别时候,散列值会发生冲突,则内部有相应的解决冲突的办法

第三步:在该位置上存入值

for i in range(2, 2):

    print(i)

键值对的访问过程

d["age"]

第一步:计算要访问的键的散列值

第二步:根据计算的散列值,通过一定的规则,确定其在散列表中的位置

第三步:读取该位置上存储的值

如果存在,则返回该值  

如果不存在,则报错KeyError

3、小结

(1)字典数据类型,通过空间换时间,实现了快速的数据查找

也就注定了字典的空间利用效率低下

(2)因为散列值对应位置的顺序与键在字典中显示的顺序可能不同,因此表现出来字典是无序的

回顾一下 N >> n
如果N = n,会产生很多位置冲突

思考一下开头的小例子,为什么字典实现了比列表更快速的查找

9.1.3.字符串的实现

通过紧凑数组实现字符串的存储,即数组的每个元素就是字符串的每个字符。

数据在内存中是连续存放的,效率更高,节省空间

思考一下,同为序列类型,为什么列表采用引用数组,而字符串采用紧凑数组

9.1.4.可变与不可变类型

1、不可变类型:数字、字符串、元组

在生命周期中保持内容不变

换句话说,改变了就不是它自己了(id变了)

不可变对象的 += 操作 实际上创建了一个新的对象

x = 1

y = "Python"

print("x id:", id(x))

print("y id:", id(y))

x id: 140718440616768

y id: 2040939892664

x += 2

y += "3.7"

print("x id:", id(x))

print("y id:", id(y))

x id: 140718440616832

y id: 2040992707056

元组并不是总是不可变的

t = (1,[2])

t[1].append(3)

print(t)

(1, [2, 3])

2、可变类型:列表、字典、集合

id 保持不变,但是里面的内容可以变

可变对象的 += 操作 实际在原对象的基础上就地修改

ls = [1, 2, 3]

d = {"Name": "Sarah", "Age": 18}

print("ls id:", id(ls))

print("d id:", id(d))

ls id: 2040991750856

d id: 2040992761608

ls += [4, 5]

d_2 = {"Sex": "female"}

d.update(d_2)            # 把d_2 中的元素更新到d中

print("ls id:", id(ls))

print("d id:", id(d))

ls id: 2040991750856

d id: 2040992761608

3.列表操作的几个小例子

【例1】 删除列表内的特定元素

方法1 存在运算删除法

缺点:每次存在运算,都要从头对列表进行遍历、查找、效率低

alist = ["d", "d", "d", "2", "2", "d" ,"d", "4"]

s = "d"

while True:

    if s in alist:

        alist.remove(s)

    else:

        break

print(alist)

['2', '2', '4']

方法2 一次性遍历元素执行删除

alist = ["d", "d", "d", "2", "2", "d" ,"d", "4"]

for s in alist:

    if s == "d":

        alist.remove(s)      # remove(s) 删除列表中第一次出现的该元素

print(alist)

['2', '2', 'd', 'd', '4']

解决方法:使用负向索引

alist = ["d", "d", "d", "2", "2", "d" ,"d", "4"]

for i in range(-len(alist), 0):

    if alist[i] == "d":

        alist.remove(alist[i])      # remove(s) 删除列表中第一次出现的该元素

print(alist)

['2', '2', '4']

【例2】 多维列表的创建

ls = [[0]*10]*5

ls

[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

ls[0][0] = 1

ls

[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

9.2.简洁的语法

9.2.1.解析语法

前面案例中创建多维列表,由于直接*5,列表每个元素的位置是一样的。

如何解决这个问题?

ls = [[0]*10 for i in range(5)]

ls

[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

ls[0][0] = 1

ls

[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

1、解析语法的基本结构——以列表解析为例(也称为列表推导)

[expression for value in iterable if conditihon]

三要素:表达式、可迭代对象、if条件(可选)

执行过程

(1)从可迭代对象中拿出一个元素

(2)通过if条件(如果有的话),对元素进行筛选

  若通过筛选:则把元素传递给表达式  

  若未通过:  则进入(1)步骤,进入下一次迭代

(3)将传递给表达式的元素,代入表达式进行处理,产生一个结果

(4)将(3)步产生的结果作为列表的一个元素进行存储

(5)重复(1)~(4)步,直至迭代对象迭代结束,返回新创建的列表

# 等价于如下代码

result = []

for value in iterale:

    if condition:

        result.append(expression)

【例】求20以内奇数的平方

squares = []

for i in range(1,21):

    if i%2 == 1:

        squares.append(i**2)

print(squares)   

[1, 9, 25, 49, 81, 121, 169, 225, 289, 361]

squares = [i**2 for i in range(1,21) if i%2 == 1]

print(squares)

[1, 9, 25, 49, 81, 121, 169, 225, 289, 361]

支持多变量

x = [1, 2, 3]

y = [1, 2, 3]

results = [i*j for i,j in zip(x, y)]

results

[1, 4, 9]

支持循环嵌套

colors = ["black", "white"]

sizes = ["S", "M", "L"]

tshirts = ["{} {}".format(color, size) for color in colors for size in sizes]

tshirts

['black S', 'black M', 'black L', 'white S', 'white M', 'white L']

2、其他解析语法的例子

解析语法构造字典(字典推导)

squares = {i: i**2 for i in range(5)}

for k, v in squares.items():

    print(k, ":  ", v)

0 :   0

1 :   1

2 :   4

3 :   9

4 :   16

解析语法构造集合(集合推导)

squares = {i**2 for i in range(10)}

squares

{0, 1, 4, 9, 16, 25, 36, 49, 64, 81}

生成器表达式

squares = (i**2 for i in range(10))

squares

at 0x000001DB37A58390>

colors = ["black", "white"]

sizes = ["S", "M", "L"]

tshirts = ("{} {}".format(color, size) for color in colors for size in sizes)

for tshirt in tshirts:

    print(tshirt)

black S

black M

black L

white S

white M

white L

9.2.2.条件表达式

基本语法:

expr1 if condition else expr2

【例】将变量n的绝对值赋值给变量x

n = -10

if n >= 0:

x = n

else:

    x = -nx

10

n = -10

x = n if n>= 0 else -n

x

10

条件表达式和解析语法简单实用、运行速度相对更快一些,相信大家会慢慢的爱上它们

9.3.生成器、迭代器和装饰器

9.3.1.生成器

正常生成1000000个元素的列表

ls = [i**2 for i in range(1, 1000001)]

for i in ls:

    pass

缺点:占用大量内存

生成器

(1)采用惰性计算的方式

(2)无需一次性存储海量数据

(3)一边执行一边计算,只计算每次需要的值

(4)实际上一直在执行next()操作,直到无值可取

1、生成器表达式

海量数据,不需存储

squares = (i**2 for i in range(1000000))

for i in squares:

    pass

求0~100的和

无需显示存储全部数据,节省内存

sum((i for i in range(101)))

5050

2、生成器函数——yield

生成斐波那契数列

数列前两个元素为1,1 之后的元素为其前两个元素之和

def fib(max):

    ls = []

    n, a, b = 0, 1, 1

    while n < max:

        ls.append(a)

        a, b = b, a + b

        n = n + 1

    return ls

 

fib(10)

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

构造生成器函数

在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行,只有在调用的时候才生成,不调用的时候,并不会计算和存储。

def fib(max):

    n, a, b = 0, 1, 1

    while n < max:

        yield a

        a, b = b, a + b

        n = n + 1

        

fib(10)

for i in fib(10):

    print(i)

1

1

2

3

5

8

13

21

34

55

9.3.2.迭代器

 

1、可迭代对象

可直接作用于for循环的对象统称为可迭代对象:Iterable

(1)列表、元组、字符串、字典、集合、文件

可以使用isinstance()判断一个对象是否是Iterable对象

from collections import Iterable

isinstance([1, 2, 3], Iterable)

True

isinstance({"name": "Sarah"}, Iterable)

True

isinstance('Python', Iterable)

True

(2)生成器

squares = (i**2 for i in range(5))

isinstance(squares, Iterable)

True

生成器不但可以用于for循环,还可以被next()函数调用

print(next(squares))

print(next(squares))

print(next(squares))

print(next(squares))

print(next(squares))

0

1

4

9

16

直到没有数据可取,抛出StopIteration

print(next(squares))

StopIteration:

2.迭代器

可以被next()函数调用并不断返回下一个值,直至没有数据可取的对象称为迭代器:Iterator

可以使用isinstance()判断一个对象是否是Iterator对象

(1) 生成器都是迭代器

from collections import Iterator

squares = (i**2 for i in range(5))

isinstance(squares, Iterator)

True

(2) 列表、元组、字符串、字典、集合不是迭代器

isinstance([1, 2, 3], Iterator)

False

可以通过iter(Iterable)创建迭代器

isinstance(iter([1, 2, 3]), Iterator)

True

for item in Iterable 等价于:

先通过iter()函数获取可迭代对象Iterable的迭代器

然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item

当遇到StopIteration的异常后循环结束

(3)zip enumerate 等itertools里的函数是迭代器

x = [1, 2]

y = ["a", "b"]

zip(x, y)

for i in zip(x, y):

    print(i)

isinstance(zip(x, y), Iterator)

(1, 'a')

(2, 'b')

True

numbers = [1, 2, 3, 4, 5]

enumerate(numbers)

for i in enumerate(numbers):

    print(i)

isinstance(enumerate(numbers), Iterator)

(0, 1)

(1, 2)

(2, 3)

(3, 4)

(4, 5)

True

4文件是迭代器

with open("测试文件.txt", "r", encoding = "utf-8") as f:

    print(isinstance(f, Iterator))

True

(5)迭代器是可耗尽的

squares = (i**2 for i in range(5))

for square in squares:

    print(square)

0

1

4

9

16

(6)range()不是迭代器

numbers = range(10)

isinstance(numbers, Iterator)

False

print(len(numbers))   # 有长度

print(numbers[0])     # 可索引

print(9 in numbers)   # 可存在计算

next(numbers)         # 不可被next()调用

10

0

True

TypeError: 'range' object is not an iterator

for number in numbers:

    print(number)

9.3.3.装饰器

1、需求的提出

(1)需要对已开发上线的程序添加某些功能

(2)不能对程序中函数的源代码进行修改

(3)不能改变程序中函数的调用方式

比如说,要统计每个函数的运行时间

2、函数对象

函数是Python中的第一类对象

(1)可以把函数赋值给变量

(2)对该变量进行调用,可实现原函数的功能

def square(x):

    return x**2

print(type(square))      # square 是function类的一个实例

pow_2 = square          # 可以理解成给这个函数起了个别名pow_2

print(pow_2(5))

print(square(5))

25

25

可以将函数作为参数进行传递

3、高阶函数

(1)接收函数作为参数

(2)或者返回一个函数

满足上述条件之一的函数称之为高阶函数

def square(x):

    return x**2

 

def pow_2(fun):

    return fun

 

f = pow_2(square)

f(8)

64

print(f == square)

True

4、 嵌套函数

在函数内部定义一个函数

def outer():

    print("outer is running")

    

    def inner():

        print("inner is running")

        

    inner()

 

outer()

outer is running

inner is running

5、闭包

闭包:

延伸了作用域的函数

如果一个函数定义在另一个函数的作用域内,并且引用了外层函数的变量,则该函数称为闭包

闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)

def outer():

    x = 1

    z = 10

    

    def inner():

        y = x+100

        return y, z

        

    return inner

 

f = outer()                # 实际上f包含了inner函数本身+outer函数的环境

print(f)

.inner at 0x000001BE11B1D730>

print(f.__closure__)         # __closure__属性中包含了来自外部函数的信息

for i in f.__closure__:

    print(i.cell_contents)

(, )

1

10

res = f()

print(res)

(101, 10)

一旦在内层函数重新定义了相同名字的变量,则变量成为局部变量

def outer():

    x = 1

    

    def inner():

        x = x+100  # x就变为局部变量,这里会报错

        return x

        

    return inner

 

f = outer()             

f()

UnboundLocalError: local variable 'x' referenced before assignment

nonlocal允许内嵌的函数来修改闭包变量

def outer():

    x = 1

    

    def inner():

        nonlocal x

        x = x+100

        return x  

    return inner

 

f = outer()             

f()

1

101

6、一个简单的装饰器

嵌套函数实现

import time

def timer(func):

    

    def inner():

        print("inner run")

        start = time.time()

        func()

        end = time.time()

        print("{} 函数运行用时{:.2f}秒".format(func.__name__, (end-start)))

    

    return inner

 

def f1():

    print("f1 run")

    time.sleep(1)

 

f1 = timer(f1)             # 包含inner()和timer的环境,如传递过来的参数func

f1()

inner run

f1 run

f1 函数运行用时1.00秒

语法糖

import time

def timer(func):

    

    def inner():

        print("inner run")

        start = time.time()

        func()

        end = time.time()

        print("{} 函数运行用时{:.2f}秒".format(func.__name__, (end-start)))

    

    return inner

@timer                      # 相当于实现了f1 = timer(f1)

def f1():

    print("f1 run")

    time.sleep(1)

    

f1()

inner run

f1 run

f1 函数运行用时1.00秒

7、装饰有参和有返回值函数

有参

import time

 

def timer(func):

    

    def inner(*args, **kwargs):

        print("inner run")

        start = time.time()

        func(*args, **kwargs)

        end = time.time()

        print("{} 函数运行用时{:.2f}秒".format(func.__name__, (end-start)))

    

    return inner

 

@timer                # 相当于实现了f1 = timer(f1)

def f1(n):

    print("f1 run")

    time.sleep(n)

 

f1(2)

inner run

f1 run

f1 函数运行用时2.00秒

被装饰函数有返回值的情况

import time

 

def timer(func):

    

    def inner(*args, **kwargs):

        print("inner run")

        start = time.time()

        res = func(*args, **kwargs)

        end = time.time()

        print("{} 函数运行用时{:.2f}秒".format(func.__name__, (end-start)))

        return res

    

    return inner

 

@timer                   # 相当于实现了f1 = timer(f1)

def f1(n):

    print("f1 run")

    time.sleep(n)

    return "wake up"

 

res = f1(2)

print(res)

inner run

f1 run

f1 函数运行用时2.00秒

wake up

8、带参数的装饰器

装饰器本身要传递一些额外参数

需求:有时需要统计绝对时间,有时需要统计绝对时间的2倍

def timer(method):

    

    def outer(func):

    

        def inner(*args, **kwargs):

            print("inner run")

            if method == "origin":

                print("origin_inner run")

                start = time.time()

                res = func(*args, **kwargs)

                end = time.time()

                print("{} 函数运行用时{:.2f}秒".format(func.__name__, (end-start)))

            elif method == "double":

                print("double_inner run")

                start = time.time()

                res = func(*args, **kwargs)

                end = time.time()

                print("{} 函数运行双倍用时{:.2f}秒".format(func.__name__, 2*(end-start)))

            return res

    

        return inner

    

    return outer

 

@timer(method="origin")  # 相当于timer = timer(method = "origin")   f1 = timer(f1)

def f1():

    print("f1 run")

    time.sleep(1)

    

@timer(method="double")

def f2():

    print("f2 run")

    time.sleep(1)

 

f1()

print()

f2()

inner run

origin_inner run

f1 run

f1 函数运行用时1.00秒

 

inner run

double_inner run

f2 run

f2 函数运行双倍用时2.00秒

9、何时执行装饰器

一装饰就执行,不必等调用

func_names=[]

def find_function(func):

    print("run")

    func_names.append(func)

    return func

 

@find_function

def f1():

    print("f1 run")

    

@find_function

def f2():

    print("f2 run")

    

@find_function

def f3():

    print("f3 run")

run

run

run

for func in func_names:

    print(func.__name__)

    func()

    print()

f1

f1 run

f2

f2 run

f3

f3 run

9.4.作业练习

数据类型的底层实现:

1、以下两段程序分别会输出怎样的结果?请运行验证,并给出理由

代码1:

def f1(ls=[]):

    ls.append(1)

    return ls

 

print(f1())

print(f1())

print(f1())

 

代码2:

person = {"name": "", "id": 0}

team = []

for i in range(3):

    x = person

    x["id"] = i

    team.append(x)

team[0]["name"] = "Peter" 

team[1]["name"] = "Paul" 

team[2]["name"] = "Mary" 

 

print(team[1])

print(team)

 

简洁的语法:

2、用列表推导实现一个过滤器

*实现一个判断数字n是否为素数的函数isprime(n);

*利用列表推导,获得100以内的素数列表;

3、使用列表推导,实现两列表对应元素的操作

获得新列表z,列表内元素

z[i] = pow(x[i], y[i])

x = [1,2, 3, 4]

y = [0,2, 3, 1]

4、使用条件表达式,将x,y 中的最大值赋值给z

编程题:

5、构造一个生产n 以内素数的生成器,与题2进行相互验证。

6、某大型网上购物网站进行中秋节优惠促销活动,请在不改变原计费函数

实现原计费函数 charge(商品名称, 商品数量 )。

假设只有三种商品,商品名称和单价存储在字典{“water”:1.5,“egg”: 1,“meat”: 15}中;

假设每次只购买一种商品,购买数量1 ~ 5 件, 不打折;购买数量6 ~ 10 件,打95 折;购买数量大于10 打9 折;

返回商品应付总货款。

在不改变原计费函数源代码和调用方式的前提下,增加如下功能:

n 每次 charge 函数被调用时,输出“中秋节快乐!”;

n 在原计费函数 charge 返回总价的基础上,对总价打8 折。

 

答案:

  1. 代码1:

[1]

[1, 1]

[1, 1, 1]

代码2:

{'name': 'Mary', 'id': 2}

[{'name': 'Mary', 'id': 2}, {'name': 'Mary', 'id': 2}, {'name': 'Mary', 'id': 2}]

2.

*是否为素数的函数

from math import sqrt

def is_prime(num):

    '''判断一个数是否为素数'''

    if num == 1:

        return False

    for i in range(2, int(sqrt(num)) + 1):

        if num % i == 0:

            return False

    return True

 

*100以内的素数列表

[i for i in range(1, 100) if is_prime(i)]

3.

from math import pow

x = [1, 2, 3, 4]

y = [0, 2, 3, 1]

z = [pow(x[i], y[i]) for i in range(len(x))]

z

[1.0, 4.0, 27.0, 4.0]

4.

x = 10

y = 12

z = x if x > y else y

z

12

5.

#coding=utf-8

# 参考Blog:https://blog.csdn.net/ZSGG_ACM/article/details/51584624

# '埃式素数生成法'

 def odd_list():

    '''奇数生成器(不包括1)生成的是一个无限序列'''

    n = 1

    while True:

        n += 2

        yield n

 

def filter_not_prime(n):

    '''过滤因子'''

    return lambda x : x % n #返回闭包

 

def primes():

    '''生成素数序列'''

    yield 2

    it = odd_list()

    while True:

        n = next(it)

        yield n

        it = filter(filter_not_prime(n), it)

 

def is_prime(num):

    '''遍历素数生成器'''

for i, x in enumerate(primes()): # enumerate迭代遍历键值对(索引:素数)

#         if x > num:

        if i > num:

            break

        else:

            print(x)

 

def run():

    is_prime(100);

    

if __name__ == "__main__":

    run()

6.

goods = {"water": 1.5, "egg": 1, "meat": 15}

def charge(goods_name, goods_count):

    '''计算购物所需花费'''

    cost = goods[goods_name] * goods_count

    if goods_count in range(6):

        return cost

    elif goods_count in range(11):

        return cost * 0.95

    elif goods_count > 10:

        return cost * 0.9        

     

def shop(goods_name, goods_count):

    print("中秋节快乐!")

    return charge(goods_name, goods_count) * 0.8

cost = shop("water", 3)cost

中秋节快乐!

3.6

cost = shop("meat", 20)cost

中秋节快乐!

216.0

 

你可能感兴趣的:(笔记,python,机器学习)