Python笔记(二)

写在前面

写本系列的目的(自用)是回顾已经学过的知识、记录新学习的知识或是记录心得理解,方便自己以后快速复习,减少遗忘。python之前学过但学得不牢,尤其是列表、元组、字典、面向对象编程部分及python一些库的使用,因此基础部分只是简单罗列语法,快速复习一下。遇到其他问题再额外补充。Python是函数多且杂,在学习阶段并不需要知道所有函数,只需要熟悉python的语法,在未来碰到特定函数时查询即可。

Part 1 基础知识

该部分主要通过python3菜鸟教程来进行复习,记录笔记。

三、条件控制

python的条件控制语句很简单,和C++区别不大。

1、if语句

if语句的关键字是if-elif-else,每个条件都要使用冒号:,基本语法是:

if condition_1:
    statement_1
elif condition_2:
    statement_2
else:
    statement_3

elif和else可以没有。以下是一个简单的实例:

var = 20

if var < 0:
    print("var是负数")
elif var == 0:
    print("var是0")
else:
    print("var是正数")

if语句同样可以嵌套,将if...elif...else 结构放在另外一个 if...elif...else 结构中

score = 90

if score >= 80:
     if score >= 90:
        print("A")
     else: 
        print("B")
else:
     print("C")

2、match...case

python中没有switch...case,但在python3中添加了match...case。下面是示例

status = 404

match status:
    case 400:
        return "Bad request"
    case 404:
        return "Not found"
    case 418:
        return "I'm a teapot" 
    case _:
        return "Something's wrong with the internet"

其中,case _:类似于C++中的default,当其他 case 都无法匹配时,匹配这条,保证永远会匹配成功。也不需要break。另外,一个case也可以设置多个匹配条件,用 | 隔开。

case 401|403|404:
    return "Not allowed"

四、循环语句

1、while循环

while循环的一般语句为:

while 判断条件(condition):
    执行语句(statements)……

同样需要注意冒号和缩进,并且在python中没有do while语句,下面为求1到100的和的示例:

n = 100

sum = 0
counter = 1

while counter <= n:
    sum += counter
    counter+=1

2、for循环

Python for 循环可以遍历任何可迭代对象,如一个列表或者一个字符串。和C++的STL迭代器比较像。一般格式为:

for <variable> in <sequence>:
    <statements>
else:
    <statements>

下面为for循环的实例:

sites = ["Baidu", "Google", "Runoob", "Taobao"]

for site in sites:
    print(site)

除了遍历列表,也可以遍历字符串:

word = 'Baidu'

for letter in word:
    print(letter)

除此之外,还可以配合range()函数使用,这里先介绍一下range()函数。range()函数是一个内置函数,用于生成不可变的整数序列,通常在for循环中控制迭代次数。

range()函数有三种调用方式:

1、range(stop):生成从0开始到stop-1的整数序列。

2、range(start, stop):生成从start开始到stop-1的整数序列。

3、range(start, stop, step):生成从start开始,step为步长,到stop-1的整数序列。类似于切片输出。

配合python的for循环可以这样使用,打印输出1~5的数字:

for number in range(1, 6):
    print(number)

3、for...else

for...else语句用于在循环结束后执行一段代码:

for x in range(6):
    print(x)
else:
    print("Finished!")

这段代码在输出0~6后会再输出Finished!

4、break和continue

在循环中使用break会直接跳出循环,而使用continue会直接进入下一层循环。下面看一个示例:

n = 5
while n > 0:
    n -= 1
    if n == 2:
        break
    print(n)

'''这段代码的输出是
4
3
之后就因为break跳出循环了
'''

n = 5
while n > 0:
    n -= 1
    if n == 2:
        continue
    print(n)

'''这段代码的输出是
4
3
1
0
因为continue跳过了输出n = 2的代码,直接进入了下一轮循环
'''

5、pass语句

pass语句是空语句,为了保持程序结构的完整性。pass 不做任何事情,一般用做占位语句,比如,你需要定义一个函数、类或者条件分支,但暂时不想编写具体实现时,可以用pass占位:

def my_function():
    pass  # 函数体为空,不执行任何操作

class MyClass:
    pass  # 类定义为空

if x > 10:
    pass  # 占位,后续再添加逻辑

在python中,代码块(如函数、类、循环)必须包含至少一条语句,若为空就会导致语法错误,使用pass就可以避免这个问题。

五、函数

1、定义并调用一个函数

函数代码块以def开头,后接函数标识符名称及()。函数内容以冒号:起始,并且缩进。return表示结束函数,选择性地返回一个值给调用方,不带return表示返回None

def hello():
    print("hello world!")

hello()

也可以更复杂点

def max(a, b)
    if a > b:
        return a
    else:
        return b

a = 4
b = 5
c = 1
print(max(a, b))
print(max(b, c))

2、参数传递

在python中,变量是没有类型的:

a = [1, 2, 3]
a = "hello"

[1, 2, 3]是list类型,hello是String类型,而a其实没有类型。它仅仅是一个对象的引用(一个指针),可以是指向 List 类型对象,也可以是指向 String 类型对象。

python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。

不可变类型:类似C++的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。

可变类型:类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响

(1)python传不可变对象
def change(a):
    print(id(a))
    a = 10
    print(id(a))

a = 1
print(id(a))
change(a)

'''输出是
4379369136
4379369136
4379369424
'''

形参和实参指向的是同一个对象(对象 id 相同),在函数内部修改形参后,形参指向的是不同的 id。

(2)python传可变对象

可变对象在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了。例如:

def change(mylist):
    mylist.append([1,2,3])
    print(mylist)
    return

mylist = [4,5,6]
change(mylist)
print(mylist)

'''输出为
[4, 5, 6, [1, 2, 3]]
[4, 5, 6, [1, 2, 3]]
'''

3、参数

在调用函数时可以有4种参数类型:必须参数,关键字参数,默认参数,不定长参数。

(1)必须参数

函数定义中必须提供的参数,调用时必须按顺序传入对应的值,否则会引发类型错误。

def add(a, b):  # a 和 b 是必需参数
    return a + b

add(3, 5)       # 正确:提供两个参数
# add(3)        # 错误:缺少参数 b,TypeError
 (2)关键字参数

调用函数时通过参数名=值的形式传递的参数,可打破参数的位置顺序,提高代码可读性

def person_info(name, age):
    print(f"Name: {name}, Age: {age}")

# 使用关键字参数调用
person_info(age=30, name="Alice")  # 正确:顺序可调整
person_info(name="Bob", age=25)    # 等价写法
 (3)默认参数

调用函数时,如果设置了默认参数且没有传递参数,则会使用默认参数。

def printinfo(name , age = 30)
    print("名字:", name)
    print("年龄:", age)

printinfo("Alice")       #没有传入年龄,使用默认参数30

printinfo("Bob", 20)     #传入了年龄,使用20
(4)不定长参数 

不定长参数允许函数接收任意数量的参数,无需在定义时明确指定参数的个数。Python 支持两种不定长参数:位置不定长参数(*args)和 关键字不定长参数(**kwargs)。

先来看位置不定长参数,通过在参数名前加*定义,接收任意数量的位置参数,并将它们封装为一个元组。

def function(*args):
    for arg in args:
        print(arg)

function(1, 2, 3)  # 输出: 1 2 3
function('a', 'b', 'c', 'd')  # 输出: a b c d

再来看关键字不定长参数,通过在参数名前加**定义,接收任意数量的关键字参数,并将它们封装为一个字典。

def function(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

function(name="Alice", age=30)  # 输出: name: Alice, age: 30
function(city="New York", country="USA", population=8.4)  
# 输出: city: New York,country:USA,population:8.4

4、匿名函数 

匿名函数也称lambda函数,是一种无需显式定义名称的小型、一次性函数。基本语法如下:

lambda arguments: expression

其中,arguments是参数列表,expression为单一表达式,其结果为函数返回值。例如,以下是一个简单的匿名函数:

add = lambda x, y : x+y
print(add(3, 5))

匿名函数无需命名,可以直接作为参数传递,例如应用到map()函数上。map()函数是一个内置函数,用于将一个函数应用到可迭代对象的每个元素上。基本语法是map(function, iterable)

下面来看一个例子:

numbers = [1, 2, 3]

squares = list(map(lambda x: x**2, numbers))
'''这里,匿名函数是lambda x : x**2
map()函数的作用是将每个元素都作用到函数上,这里的元素列表是numbers,也就是将每个number传入匿名函数
list()的作用是将得到的数据转换为列表'''
print(squares)  # 输出: [1, 4, 9]

除了map()外,还有filter()和reduce()都能很方便地配合匿名函数使用

filter():根据函数的返回值筛选元素,返回满足条件的元素组成的迭代器。例如:

# 筛选偶数
numbers = [1, 2, 3, 4, 5]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # 输出: [2, 4]

reduce():将函数应用于可迭代对象的前两个元素,然后将结果与下一个元素继续计算,直到完成所有元素的累积。例如:

Part 2

一、Python推导式

Python 推导式是一种独特的数据处理方式,可以从一个数据序列构建另一个新的数据序列的结构体。适用于生成列表、字典、集合和生成器。

1、列表推导式

列表推导式的核心结构为:

[expression for item in iterable]

其中,expression是对每个元素的操作或转换,item是从可迭代对象中取出的元素,iterable是被遍历的可迭代元素。例如,生成0到4的平方列表:

squares = [x**2 for x in range(5)]
print(squares)  #输出[0,1,4,9,16]

从这里就能理解expression了,这里我们选择的是对原列表中小于4的数取平方并组成新列表。除此之外,还可以添加条件过滤,如下:

[expression for item in iterable if condition]

先直接看一个示例:

names = ['Bob','Tom','alice','Jerry','Wendy','Smith']

new_names = [name.upper() for name in names if len(name)>3]

print(new_names)

'''结果是
['ALICE', 'JERRY', 'WENDY', 'SMITH']
'''

这里的expression是name.upper(),将每个元素的字母大写。条件是len(name)>3,也就是名字长度大于3个字符。那么新列表就是,在原列表中,长度大于三的大写名字组成的新列表。

2、字典推导式

字典推导式的核心结构为:

{key_expression: value_expression for item in iterable}

其中key_expression是生成字典键的表达式,value_expressions是生成字典值的表达式。item是从可迭代对象中取出的元素,iterable是被遍历的可迭代对象。下面是一个简单的示例:

listdemo = ['Google','Runoob', 'Taobao']

newdict = {key:len(key) for key in listdemo}

print(newdict)
'''结果
{'Google': 6, 'Runoob': 6, 'Taobao': 6}
'''

可以看出,listdemo是key_expression,也就是新列表的键值来自于listdemo,value_expressions是len(key)。除此之外,还可以添加条件过滤,如下:

{key_expression: value_expression for item in iterable if condition}
numbers = [1,2,3,4,5]

new = {x : x**2 for x in numbers if x%2 == 0}

print(new) 

'''输出
{2:4, 4:16}
'''

最后,还有一个应用场景,交换字典的键和值:

original  = {'a':1, 'b':2}

new = {value : key for key, value in original}

print(new)

3、集合推导式

集合推导式的核心结构是:

{expression for item in iterable}

下面看一个示例,生成数字的平方集合(注意集合会自动去重):

square = {x**2 for x in [1, 2, 2, 3]}

print(square)

'''结果是
{1, 4, 9}
'''

也可以添加条件过滤:

{expression for item in iterable if condition}

示例如下,生成偶数的平方集合:

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

new = {x**2 for x in numbers if x%2 == 0}

print(new)
'''结果是,注意集合元素无序
{16, 4, 36}
'''

4、元组推导式

没有直接的元组推导式,元组推导式可以利用 range 区间、元组、列表、字典和集合等数据类型,快速生成一个满足指定需求的元组。如果不加转换为元组,就会成为生成器(生成器见下)。

tuple_result = tuple(x**2 for x in range(5))  # 直接转换为元组

print(tuple_result)  # 输出: (0, 1, 4, 9, 16)

二、迭代器与生成器

1、迭代器

迭代是 Python 最强大的功能之一,是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。需要注意的是,迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

(1)迭代器的创建与使用

迭代器的两个基本方法是:iter()和next()

其中,iter()是创建迭代器,next(it)会返回迭代器当前指向的元素,并将迭代器移动到下一个位置,类似后置++。

my_list = [1, 2, 3]
it = iter(my_list)  # 创建迭代器

print(next(it))  # 输出: 1
print(next(it))  # 输出: 2
print(next(it))  # 输出: 3
# print(next(it))  # 报错: StopIteration

迭代器对象也可以通过常规for语句进行遍历:

list = [1, 2, 3, 4]

it = iter(list)

for x in it:
    print(x, end = " ")
'''输出
1 2 3 4
'''
 (2)自定义迭代器类

可以通过实现__iter__() 和 __next__()方法创建自定义迭代器。如果有了解过面向对象编程,就会知道,和C++相同,Python也有构造函数,Python 的构造函数为 __init__(), 它会在对象初始化的时候执行。这里先放上自定义迭代器的代码,可以在学习面向对象的时候回顾。

class Counter:
    def __init__(self, max_num):  # 有参构造函数,起到初始化的作用,这里设置迭代器最大值,初始值
        self.max = max_num       # 最大值由用户传入 
        self.current = 0        #初始值为0

    def __iter__(self):
        return self             # 返回迭代器自身

    def __next__(self):
        if self.current < self.max:
            value = self.current
            self.current += 1
            return value
        else:
            raise StopIteration  # 迭代结束

# 使用自定义迭代器
counter = Counter(3)  # 迭代器的最大值设置为3       
for num in counter:
    print(num)  # 输出: 0 1 2

其中,StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。

2、生成器

生成器是一种特殊的迭代器,它允许你以更简洁的方式创建迭代器。跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作。使用了yield的函数被称为生成器。

(1)生成器函数

生成器函数是通过yield关键字定义的函数,每次调用next()时会暂停并保存当前状态,下次调用时从暂停处继续执行,见以下示例:

def fibonacci():                 #相当于创建了一个迭代器,迭代器的数字遵从斐波那契数列
    a, b = 0, 1
    while True:
        yield a                  # 这句代码暂停并返回当前值
        a, b = b, a + b          # 下次调用从这里继续

# 使用生成器
fib = fibonacci()  
print(next(fib))  # 输出: 0
print(next(fib))  # 输出: 1
print(next(fib))  # 输出: 1

#也可以通过for循环访问
for value in fib:
    print(value)
(2)生成器表达式

生成器表达式类似于列表推导式,但是使用圆括号,返回一个生成器对象。基本语法如下:

gen = (expression for item in iterable if condition)

示例如下:

squares = (x**2 for x int range(5))   #生成器中包含0 1 4 9 16

print(next(squares))   # 输出 0

print(next(squares))   # 输出 1 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值