从零开始的 python

从零开始的 python

引用官方库函数/常量之类的

from __ import __
print
print('Hello,World',end='')

python 中 print 默认换行,所以用 ,end= 来自定义结尾句

自定义函数

def ___():
	
	
	return 
	

在交互式环境下,要多打一行空行

注:在 def 的参数可以直接

def exp(n,d=10)

如果执行 exp(23333) ,d 就默认为 10

如果是 exp(2333,15) ,d 仍然为 15

编译命令

python -i

表示执行交互式,会先运行一次程序,然后开始交互

python -m doctest xxx.py

表示文档差错(似乎是一种还可以的Debug方式?)

python -m doctest -v ex.py

详细版

使用方式为以 >>> 在注释中打出 交互命令 和 期望结果 ,然后如果有不匹配就会报错。

def divide_exact(n,d):
    """
    return sth about deivde
    >>> q, r= divide_exact(2013,10)
    >>> q
    201
    >>> r
    2
    """
    return n//d, n%d
q, r= divide_exact(2013,10)
#print(q,r)

条件语句

def abs(a):
    if a < 0:
        return -a
    elif a > 0:
        return a
   

else if = elif (仍然有 else 的用法,但似乎不能用 else if?)

PS: 实参会在计算后再传递

python 有从左到右计算的特性(似乎叫短路?)

eg:

return x>0 and sqrt(x)>10

如果给一个 x<0 ,那么也不会报错,以为在 x>0 时就已经返回 false 了。

循环

while i<3:
	i = i+1
	total = total + i

assert

就是断言

assert conditon,message

若 condition 为假,就print message

def 嵌套(似乎叫闭包)

def make_adder(n):
    def adder (k):
        return k+n
    return adder

这个挺有意思的,return 了一个函数,相当于你可以为直接定义一个函数,like:

add_three = make_adder(3)

就喜提 add_three()

PS:

python 的函数似乎没有前后声明的要求,比如:

def f(x,y):
    return g(x)

def g(a):
    return a+233

result = f(1,2)

print(result)

这个代码就可以正常运行

嵌套还可以这么玩:

def compose1(f ,g):
    def h(x):
        return f(g(x))
    return h

def f1 (x):
    return x-1

def p1 (x):
    return x*2

us = compose1(f1 , p1)

a=us(3)

print(a)

有意思捏

lambda

S = lambda x: x*x

可以用来定义简易函数

这样的 S 就是 S(x) 了

当然,也可以作为传参:

def my_func(x,y,operation) 
	return operation(x,y)

result = my_func(3, 4, lambda a,b: a*b)

还可以

map(lambda x: x*x,[y for y in range(10)])

or

words = ["apple", "banana", "cherry"]
uppercase_words = list(map(lambda x: x.upper(), words))
print(uppercase_words)  # 输出:['APPLE', 'BANANA', 'CHERRY']

简洁

装饰器

byd我看了半天都没懂

大概是利用函数做传参

@XXXXX
def func(x):

然后就起到一个

funck=XXXXX(funck)

的作用

举个例子:(from https://www.bilibili.com/video/BV1Gu411Q7JV/)

import time

def timeit(f):

    def wrapper(x):
        start = time.time()
        ret = f(x)
        print(time.time() - start)
        return ret
    
    return wrapper

@timeit
def my_func(x):
    time.sleep(x)

my_func(1)

结果: 1.0001389980316162

什么意思呢?就是在有 @timeit 在 My_func(x) 的 def 上面时, 会将 my_func(x) 作为一个参数 传入 timeit 中,

然后 timeit 镶嵌了一个 wrapper ,在其中进行 修饰 操作,并且会返回 ret wrapper ,就是 my_func(x) 被完美执行的同时,会把修饰代码一并做了,感觉调试时候会很棒。

进阶版

import time

def timeit(f):

    def wrapper(*args, **kwargs):
        start = time.time()
        #time.sleep(1)
        ret = f(*args, **kwargs)
        print(time.time() - start)
        return ret
    
    return wrapper

@timeit
def my_func(x):
    time.sleep(x)

@timeit
def add(x,y):
    #time.sleep(2)
    return x+y

my_func(1)

add(2,3)

差异: *args , **kwargs

作用:允许任意长度的参数乱穿了。不然像第一种代码, add(x,y) 是 2 个参数,而 wrapper , ret 是一个参数就会错。

LIST (数组来咯)

mylist = [1,2,3,4,5]
#or
another_list = list(["apple","banana"])

ps: python的字符可以混搭

下标为 -1 时 输出最后一个元素

操作
my_list.append(6)  # 在列表末尾添加元素
my_list.insert(2, 10)  # 在指定位置插入元素
my_list.remove(3)  # 删除指定元素
my_list[0] = 100  # 修改指定索引位置的元素
print(my_list.index(4))  # 查找元素的索引位置

.insert 就是把原本该位置上的往后挪,如果插入的地方大于end,就会直接插在最后一个

切片
print(my_list[1:4])  # 获取索引1到索引3的子列表
print(my_list[:3])  # 获取从开头到索引2的子列表
print(my_list[2:])  # 获取从索引2到末尾的子列表
遍历
print(len(my_list))  # 输出列表的长度
for item in my_list:
    print(item)  # 逐个输出列表中的元素
其他操作
my_list.sort()  # 对列表进行排序
my_list.reverse()  # 反转列表中的元素顺序
concatenated_list = my_list + another_list  # 拼接两个列表
count = my_list.count(2)  # 计算指定元素的出现次数

字符串的运用不能说十分相似,只能说一模一样

Dictionary (字典)

就是 hash

dict = { 'Name ' : 'HEWO' , 'AGE' : 18 }

添加也可以直接暴力赋值即可(python学多了看什么都是直接赋)

删除:

del dict[XXX] 

or

dict.clear() # 清空
del dict #删库跑路

PS:

key 重复后后面的会覆盖前面的

元组

不可更改的 list

用()

tup1 = ('physics', 'chemistry', 1997, 2000)
tup2 = (1, 2, 3, 4, 5 )
tup3 = "a", "b", "c", "d"

不能修改,但可以使用

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')
 
# 以下修改元组元素操作是非法的。
# tup1[0] = 100
 
# 创建一个新的元组
tup3 = tup1 + tup2
print tup3
结构体(data abstration)

来自 gpt 的例子:

class BankAccount:
    def __init__(self, account_number, balance):
        self.account_number = account_number
        self.balance = balance

    def deposit(self, amount):
        self.balance += amount

    def withdraw(self, amount):
        if self.balance >= amount:
            self.balance -= amount
        else:
            print("Insufficient funds!")

    def get_balance(self):
        return self.balance


# 创建银行账户对象
account = BankAccount("123456789", 1000)

# 存款
account.deposit(500)

# 取款
account.withdraw(200)

# 获取余额
balance = account.get_balance()
print("Account balance:", balance)

可以看见,定义类 用 class

有个

def __init__(,,,,,):

来初始化

然后就往里面 def 就是了

Iterator (迭代器)

获取 :

s = []
d = iter (s)

下一个:

next (s)

注意,iterator 不用赋值( s = next(s) ),直接 next 即可

对于字典来说:

k = iter(d.keys()) # or iter (d)

在 python3.6 以后,字典都是按照添加先后排序。

PS: 当你中途改了字典后 ,你的迭代器就会失效

如果用 for 的话:

ri = iter (r)
for i in ri :
    print(i)
    

起始点就是 ri 对应的数值,用过后 ri 是会改变的!

enumerate
enumerate (iterable , start = 0)

相当于返回 索引 + 值

fruits = ['apple', 'banana', 'orange']
for index, fruit in enumerate(fruits, start=1):
    print(index, fruit)  # 输出:1 'apple', 2 'banana', 3 'orange'

还可以像 c 一样玩下标:

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

for index , value in enumerate(m):
    m[index] = value * 2

print(m)

如果只想要下标的话可以这样:

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

# 使用索引在循环中修改列表元素
for i in range(len(my_list)):
    my_list[i] = my_list[i] * 2  # 修改元素

print(my_list)  # 输出:[2, 4, 6, 8, 10]

不过值得说的是,不建议在 python 中玩太多下标,毕竟 python 已经够方便了,比如:

m = [1,2,3,4,5]
n_m = []
for i in m:
    n_m.append(i*2)
   	
m = n_m

内置迭代器

就好像是内置函数一样:

  1. iter():用于创建一个迭代器对象,可以遍历可迭代对象中的元素。
  2. next():用于从迭代器中获取下一个元素。
  3. reversed():返回一个反向迭代器,用于逆序遍历一个序列。
  4. enumerate():返回一个由索引-元素对组成的迭代器,可以同时获取元素的索引和值。
  5. zip():返回一个将多个可迭代对象中的元素配对的迭代器。
  6. map():对可迭代对象中的每个元素应用一个函数,并返回一个迭代器。
  7. filter():根据指定的条件筛选可迭代对象中的元素,并返回一个迭代器。
  8. sorted():返回一个对可迭代对象进行排序的迭代器。
  9. iteritems()(Python 2)/ items()(Python 3):返回一个迭代器,用于遍历字典中的键值对。
  10. itervalues()(Python 2)/ values()(Python 3):返回一个迭代器,用于遍历字典中的值。
  11. iterkeys()(Python 2)/ keys()(Python 3):返回一个迭代器,用于遍历字典中的键。
  12. itertools.count():返回一个从指定值开始的无限整数迭代器。
  13. itertools.cycle():返回一个无限循环迭代给定的可迭代对象。
  14. itertools.islice():返回一个迭代器,用于对可迭代对象进行切片操作。
  15. itertools.chain():将多个可迭代对象连接起来,返回一个迭代器。
  16. itertools.compress():根据指定的选择器迭代器,对可迭代对象进行筛选,返回一个迭代器。
  17. itertools.groupby():根据指定的键函数对可迭代对象进行分组,返回一个迭代器。
  18. itertools.tee():返回多个独立的迭代器,用于同时遍历可迭代对象。

(直接抄的GPT)

ZIP

打包函数

names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
scores = [90, 85, 95]

# 将列表的对应位置元素打包成元组
zipped = zip(names, ages, scores)

# 遍历打包后的元组
for item in zipped:
    print(item)

zip 会一一对应,如果对不上,length 就是最短的那个。

注意,zip函数返回的是个迭代器。

如果想搞个list,就这样:

names = ['Alice', 'Bob', 'Charlie','hewo']
ages = [25, 30, 35,114514]
scores = [90, 85, 95,100]

# 将列表的对应位置元素打包成元组,然后用list封装
mylis = list(zip(names,ages,scores))

for i in mylis:
    print(i)

generator(生成器)

def ppp(x):
...     yield x
...     yield -x
	

使用 yield 而不是 return 是 generator 和 常规函数的区别。

它返回的是一个 迭代器,比如上面的代码,第一次直接输出t就是段地址,next(t)=x,next(t)=-x;

再来个实例

def fibonacci_generator():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

# 使用生成器生成斐波那契数列的前10个数
fib = fibonacci_generator()
for _ in range(10):
    print(next(fib))

在上面的例子中,fibonacci_generator函数是一个生成器函数,它使用了yield语句来产生斐波那契数列中的每个元素。通过调用next()函数来迭代生成器,每次调用时生成器会生成一个值,然后在yield语句处暂停。在循环中,我们使用range(10)来控制生成斐波那契数列的前10个数。

来自gpt,我感觉没问题

再来个实战

def countdown(k):
    if k>0:
        yield k
        yield from countdown(k-1)
    else:
        yield 'OVER'

利用递归实现的倒计时,yield from 将新的迭代器给当前的,放在对象错误。

再来个实战:

def func(n, m):
    if n > 0 and m > 0:
        if n == m:
            yield str(m)
        for p in func(n-m,m):
            yield p + '+' +str(m)
        yield from func(n,m-1)

for p in func(6,4):
    print(p)

感觉这部分有点不一样,以后注意多适应

posted @ 2023-08-16 15:43  hewo  阅读(23)  评论(0编辑  收藏  举报