三天速成Python之Day1——阶乘、水仙花、杨辉三角

0xFF 前言

  • 随着安全卫士的项目结束,C++的学习也暂告一段落了,至此开始了第二阶段的学习。

  • 周一上来就连着3天的Python,其中第一天从基本的输入输出讲到了函数式编程。

  • 本文笔记见:语雀


Ox01 进制转换

# python 中的基本类型: int(无限长度),float(小数)
print(1024, type(1024))
print(3.14, 314e-2, type(3.14))

# 整数类型不同形式的表现(输出)
print(hex(100), bin(100), oct(100))

# 整数类型不同形式的表现(输入)
print(0b1100100, 0x64, 0o144)

# 将字符串转换成整数类型
print(int('1000'), type(int('1000')))
print(int('1000', 16), int('1000', 8))

11/12补充 小数转换

https://blog.csdn.net/fu6543210/article/details/88585469

  • 只有当n+1位数字是5的时候,容易混淆,

    如果n为偶数,则n+1位数是5,则进位,

    例如round(1.23456,3)最终变为1.235

  • 如果n为奇数,则n+1位是数5,那不进位,

    例如round(2.355,2),最终为2.35

  • 如果n为0,即没有填写n的时候,最终结果与上面相反,

    即整数部分为偶数的时候,小数位5不进位,例如(round(2.5)变为2)。

# 将字符串转小数
# 此方法容易混淆
print(round(3.1415, 3))  # 四舍五入 进位
print(round(3.45, 1))  # 四舍五入 进位
print(round(3.35, 1))  # 四舍五入 没有进位
print(round(3.5))  # 四舍五入 进位
print(round(2.5))  # 四舍五入 没有进位

# 方法二
str_s = '3.1415926'
flo_s = float(str_s)
print(flo_s, type(flo_s))
print('%.3f%%' % flo_s)
print(f'{flo_s:.3f}%')
# 方法三:Decimal()函数
from decimal import Decimal

flo_f = Decimal(flo_s).quantize(Decimal('0.000'))
print(flo_f, str(flo_f) + '%')

Ox02 列表(list[])使用

笔记

# 全局函数
print(len([1, 2, 3]))
print(min([1, 2, 3]))
print(max([1, 2, 3]))
print(list(reversed([1, 2, 3])))
print(list(sorted([1, 2, 3])))

# 内置方法
l = [1, 2, 3, 4, 5]
l.append(6)
print(l)        # 在结尾添加元素
l.insert(0, 0)
print(l)        # 在指定位置添加
l.remove(3)
print(l)        # 删除某元素(元素)
l.pop(0)
print(l)        # 删除某元素(索引),返回删除的内容
l.extend([1,2,3,4])
print(l)        # 类似列表的加法运算符

# 切片操作(序列操作)  l[a:b:c]
l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(l[:3], l[:4])         # [起始位置, 结束的索引(不包含)]
print(l[3:], l[4:])         # [起始的索引(包含), 结束位置]
print(l[::2], l[::3])       # [::间隔的个数(步长)]
print(l[:-1])               # [:负数] 倒数第n个的前一个
print(l[::-1])              # [::负数] 逆序开始计算步数
print(l[1:7:3])             # 从下标 1 开始,到下标 7 的前一个,每次遍历+

# 11/12 补充
lv = list(i + 1 for i in range(10))
print(lv[-5:])  # [后5个数]
print(lv[-5:7])  # [后5个数起,到第7个数]
print(lv[-5:-1])  # [后5个数起,到倒数第一个)	左开右闭


# 元组类型: 可以看作不变的列表,操作方式类似列表,使用 , 定义
print((1,), type((1,)))

# 元组的打包和解包(打包)
t = 1, 2, 3, 4, 5
# 元组的打包和解包(解包): 解包的过程中前面的变量数量和元组的元素数量必须保持一致
a, b, c, d, e = t

# 元组打包解包的例子
a = 1
b = 2
# 将 b 和 a 的值,也就是 2 和 1 打包成一个临时的元组,
# 然后进行解包,将 2 和 1 分别赋值给对应位置的 a 和 b
a, b = b, a


# 打包可以让函数返回多个参数,解包可以接收多个参数
def return_more():
    return 1, 2, 3


# 通过解包接收到了多个返回值
value1, value2, value3 = return_more()

Ox03 字典(dict{})使用

笔记

# 字典存储的是键值对,可以通过 {}的方式定义字典
print({'1': 1, '2': 2, '3': 3}, {})

d = dict()
# 通过索引添加键来访问对应的值,第一次赋值时会添加,接下来的操作就是修改
d['小明'] = 99
print(d)            # 添加
d['小明'] = 0
print(d)            # 修改
del d['小明']
print(d)            # 删除

# 不能访问不存在的键,在使用前通常会判断是否拥有键
if '小明' in d:
    print(d['小明'])

# 可变类型,元素可以被修改的类型: list dict set
# 不可变类型,元素不可以被修改的类型: int float bool str tuple

# 字典的键必须时不可变类型
d = {1: 1, '1': 1, True: 1, 1.1: 1, (1,): 1}

# 用于获取到字典内的一些信息
print(d.items())
print(d.values())
print(d.keys())


# 集合类型: 通过 {值,值,值} 定义非空集合,空集合使用set()定义
#   set 要求所有的数据必须时常量,且唯一
print({1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2, 1})

# 可以通过集合来保存一些唯一的数据
print(list(set([1, 2, 3, 4, 5, 6, 7, 8])))

# 集合可以用于执行数学运算中的集合运算   | ^ - +

Ox04 深拷贝浅拷贝

l1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 对列表进行赋值操作,执行的实际是浅拷贝
l2 = l1
print(hex(id(l1)), hex(id(l2)))

# 如果是浅拷贝,两个变量指向同一个地址,一方更改,另一方也受影响
l2[0] = 10
print(l1, l2)

l1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 通过 copy 方法进行深拷贝
l2 = l1.copy()
print(hex(id(l1)), hex(id(l2)))

# 拥有各自独立的空间,不会影响另外一个
l2[0] = 10
print(l1, l2)


# 动态类型: 类型在运行过程中确定,可以改变,一般不用在定义(如果有定义)时指定类型
# 静态类型: 类型在编译时确定,运行期间不变,始终保存定义时所提供的类型

# 强类型: 不同类型的变量,所能够执行的操作是不同的,例如整数相乘是乘法,字符串乘法是重复
# 弱类型: 运算不考虑类型,可以为任何类型提供计算

Ox05 循环语句补充

# 使用 range 可以快速生成一个指定规则的列表,参数同切片
print(list(range(1, 100, 3)))

# 通过 range 生成一个可迭代序列,从中取出元素,并输出
for value in range(101):
    print(value)


# while 一般用于不确定的循环,for 一般用于序列的遍历
# break 和 continue 和 C++ 的完全一致,对于break,for 和 while 有扩展语法

for i in range(100):
    # 对于 for else 或者 while else 语句,如果采用 break 跳出
    # 循环就不执行 else,如果正常退出则执行
    pass
else:
    print('正常退出')

Ox06 快速生成式

# 列表生成式: 快速生成列表
print([i for i in range(1000)])                         # 生成指定序列
print([i for i in range(1000) if i % 2 == 0])           # 生成指定序列 + 判断
print([i**2 for i in range(1000) if i % 2 == 0])        # 生成指定序列 + 判断 + 表达式
print([i*j for i in range(1, 10) for j in range(1, 10)])

import os
dir_base = r'D:\Microsoft\Visual Studio 2019\Common7\IDE\\'
print([os.path.splitext(path) for path in os.listdir(dir_base) if os.path.isfile(dir_base+path)])

# 元组生成式,改成圆括号
# 字典生成式,改成键值对的花括号
# 集合生成式,改成花括号

Ox16 函数的使用

# 函数定义的简单例子
def my_max(value1=0, value2=0):
    # 类似三目运算符的写法
    return value1 if value1 > value2 else value2


# 新的写法,可以限制传入的类型
def my_min(value1: int, value2: int) -> int:
    return value1 if value1 > value2 else value2


# pass 类似于 C 语言中的单个分号,即什么也不做,如果一个
# 函数没有显示的指定返回值,那么就返回 None
def no_return():
    pass


print(no_return())


# 参数的传递: 位置传参,按照定义顺序传参
print(my_min(10, 20))

# 参数的传递: 关键字传参,按照形参名传参(很常见)
print(my_min(value2=10, value1=20))


# 变参的传递: 传元组 *args
def args_function(*args):
    print(args, type(args))


args_function(1, 2)
args_function(1, 2, 3)


# 变参的传递: 传字典
def kwargs_function(**kwargs):
    print(kwargs, type(kwargs))


kwargs_function(a=1, b=2, c=3)
kwargs_function(a=1, b=2, c=3, d=4)


# 两种方式一般组合使用,在使用的时候,要求字典必须在后面
def all_fucntion(*args, **kwargs):
    print(args, type(args))
    print(kwargs, type(kwargs))

Ox20 课后习题

Ox21 在python的交互式接收器中(Python.exe),通过输入dir(),type(),help()

(括号中其他数值),看能看到什么结果?

参考答案:

dir(对象):返回对象(模块)中的所有方法的名字

type(对象) :返回对象的类型

help(对象) :返回对象的帮助文档


Ox22 实现列表的去重

List = [ 1,2,3,4,4,2,6,3,3,2]

参考答案:

List = [ 1,2,3,4,4,2,6,3,3,2]
List = list(set(List))
print(List)

学员答案:

def list1():
    global gList
    lst2 = list(set(gList))
    lst2.sort(key=gList.index)
    return lst2


def list2():
    global gList
    data = gList.copy()
    return sorted(set(data), key=data.index)


gList = [11, 2, 3, 4, 4, 2, 6, 3, 3, 2]

Ox23 输入n,求得n的阶乘和。

例如:输入5

输出:1! + 2! + 3!+ 4!+ 5!的值

参考答案:

#输入一个整数
n = int(input())
#定义一个函数,返回n的阶乘
def factorial(n):
    if n == 1:
        return 1;
    return n*factorial(n-1)
#定义变量记录结果
total = 0
for i in range(n+1):
    if i == 0:
        continue;
    #print(factorial(i))
    total += factorial(i)
print(total)

学员答案:

'''
n的阶乘和
'''
def t8_4_1(num: int):
    imax = 0
    for i in range(1, num + 1):
        sum2 = 1
        for j in range(1, i + 1):
            sum2 *= j
        imax += sum2
    return imax

Ox24 求得1000以内的水仙花数

参考答案:

i = 100
while i < 1000:
    a = i % 10          #个位数值
    b = (i // 10) % 10  #十位数值
    c = (i // 100) % 10 #百位数值  
    d = a*a*a + b*b*b + c*c*c
    if i == d:
        print(i)
    i += 1

学员答案:

# 水仙花
def t8_4_2(num: int):
    lv = []
    for i in range(100, num, 1):
        num_sum = 0
        for x in str(i):
            num_sum += int(x) ** 3
        if i == num_sum:
            lv.append(i)
    return lv

Ox25 打印如下图形

题8.4.3

参考答案:

def fun(n):
    for i in range(n):
        for j in range(n-i):
            print(end='  ')     #两个空格
        for k in range(2*(i-1) + 1):
            print('*',end=' ')
        print('\n')

学员答案:

#圣诞树
def t8_4_3(line: int):
    for i in range(1, line + 1):
        print(' ' * (line - i), i * '*', (i - 1) * '*', sep='')
    return '-' * line

Ox26 打印如下图型

题8.4.4

参考答案:

pass

学员答案:

# 实心菱形
def t8_4_4(line: int):
    for i in range(1, line):
        print(' ' * (line - i), i * '*', (i - 1) * '*', sep='')
    for i in range(line, 0, -1):
        print(' ' * (line - i), i * '*', (i - 1) * '*', sep='')
    return '-' * line

Ox27 打印如下图型

​ *

​ * *

​ * *

​ * *

​ * *

​ * *

​ *

答题结果:

参考答案:

def fun(n):
    for i in range(1,n):
        for j in range(1,n-i):
            print(end='  ')                 #两个空格
        for k in range(2*(i-1) + 1):
            if k == 0:                       #打印左边*
                print('*',end=' ')           #上三角
            elif k == 2*(i-1):               #打印右边的*
                print('*',end=' ')
            else:
                print(end='  ')            #两个空格
        print('\n')
#------------------------------------------------------------
    for i in range(1,n-1):
        for j in range(i):
            print(end='  ')                  #两个空格
        for k in range(n+(n-3)-2*i):         #下三角
            if k == 0:
                print('*',end=' ')
            elif k == n + (n-3)-2*i-1:
                print('*',end=' ')
            else:
                print(end='  ')
        print('\n')

学员答案:

# 空心菱形
def t8_4_5(line: int):
    for i in range(0, line):
        print(' ' * (line - i - 1), end='*')
        print(' ' * (2 * i - 1), end='')
        print('*' if i > 0 else '')
    for i in range(1, line):
        print(' ' * i, end='*')
        print(' ' * ((line - i) * 2 - 3), end='')
        print('*' if i < line - 1 else '')
    return '-' * line

Ox28 使用python实现一个列表的冒泡排序。

List = [ 20,30,40,3,6,47,25,77,15]

参考答案:

ls = [20,30,40,3,6,47,25,77,15]

for i in range(len(ls)):
    for j in range(1+i,len(ls)):
        if ls[i] > ls[j] :
            t = ls[i]
            ls[i] = ls[j]
            ls[j] = t

学员答案:

# 冒泡排序
def t8_4_6():
    ls = [20, 30, 40, 3, 6, 47, 25, 77, 15]
    for i in range(len(ls)):
        for j in range(1 + i, len(ls)):
            if ls[i] > ls[j]:
                ls[i], ls[j] = ls[j], ls[i]
    return ls

Ox29 实现一个函数,输入为n (n<15)。在函数内打印n排杨辉三角

参考答案:

def Yanghui():
    n = [1]
    while True:
        yield n
        n.append(0)
        n = [n[i] + n[i-1] for i in range(len(n))]

def fun(n):
    for i in Yanghui():
        print(i)
        n -= 1
        if n == 0:
            break
fun(10)

学员答案:

# 杨辉三角
def t8_4_7(line: int):
    if line < 0 or line > 999:
        return
    g = [1]
    for n in range(line):
        print(g)
        g.append(0)
        g = [g[i] + g[i - 1] for i in range(len(g))]
    return '↑↑↑\t8.4.7_杨辉三角'

Ox30 课外补充

生成器 - 廖雪峰的官方网站

https://www.liaoxuefeng.com/wiki/1016959663602400/1017318207388128

Ox31 斐波那契两种方法

# 斐波那契普通版
def f01_fib(line: int):
    print('-' * 9, '斐波那契')
    n, a, b = 0, 0, 1
    while n < line:
        print(b, end=' ')
        a, b = b, a + b
        n = n + 1
    return '-' * 9 + '<斐波那契'


# 斐波那契生成器
def f02_fib(line: int):
    print('-' * 9, '斐波那契')
    n, a, b = 0, 0, 1
    while n < line:
        yield b
        a, b = b, a + b
        n = n + 1
    return '-' * 9 + '<斐波那契'

但是用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIterationvalue中:

>>> g = fib(6)
>>> while True:
...     try:
...         x = next(g)
...         print('g:', x)
...     except StopIteration as e:
...         print('Generator return value:', e.value)
...         break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done

Ox32 杨辉三角的生成式

# 杨辉三角生成器
def t8_4_7_ex(line: int):
    if line < 0 or line > 999:
        return
    g = [1]
    for n in range(line):
        yield g
        g.append(0)
        g = [g[i] + g[i - 1] for i in range(len(g))]
    return '↑↑↑\t8.4.7_杨辉三角生成器'