Python语言基础

数据类型

  • 整型:int
  • 浮点型:小数,包括一般数学写法(1.234)和科学计数法(1.234e3)
  • 字符串型:字符串是以单引号或双引号括起来的任意文本,比如’hello’和"hello",字符串还有原始字符串表示法、字节字符串表示法、Unicode字符串表示法,而且可以书写成多行的形式(用三个单引号或三个双引号开头,三个单引号或三个双引号结尾)。
  • 布尔型:bool,布尔值分为TrueFalse
  • 复数型:形如1+2j.

变量命名

  • 硬性规则:
    • 变量名由字母(广义的Unicode字符,不包括特殊字符)、数字和下划线构成,数字不能开头。
    • 大小写敏感(大写的a和小写的A是两个不同的变量)。
    • 不要跟关键字和系统保留字(如函数、模块等的名字)冲突。
  • PEP 8要求:
    • 用小写字母拼写,多个单词用下划线连接。
    • 受保护的实例属性用单个下划线开头。
    • 私有的实例属性用两个下划线开头。

Python内置的数据类型转换

  • int():将数值或字符串变量转换为整型,可以指定进制
  • float():将字符串变量转为浮点型
  • str():将指定的变量转换为字符串类型,可以指定编码
  • chr():将整型变量转换为该编码对应的字符串(一个字符)
  • ord():将字符串变量(一个字符)转换为对应的编码(整型)

运算符

Python支持多种运算符,下表大致按照优先级从高到低的顺序列出了所有的运算符:

运算符描述
[]、[:]下标,切片
**指数
~、+、-按位取反, 正负号
*、/、%、//乘,除,模,整除
+、-加,减
>>、<<右移,左移
&按位与
^、|按位异或,按位或
<=、<、>、>=小于等于,小于,大于,大于等于
==、!=等于,不等于
is、is not身份运算符
in、not in成员运算符
not、or、and逻辑运算符
=、+=、-=、*=、/=、%=、//=、**=、&=、 =、^=、>>=、<<=

函数

参数种类

Python函数的参数可以分为默认参数、位置参数、关键字参数、可变参数

  • 默认参数:定义函数时,为形参提供默认值(param=10),默认参数必须位于最右端。调用函数时如果没有传入对应实参,则取默认参数
  • 位置参数:调用函数时传入实参的数量和位置必须和定义函数时一致
  • 关键字参数:调用函数时采用键值对的方式(key=value)。混合位置和关键字传参时,关键字参数必须在位置参数后。
  • 可变参数
位置参数与关键字参数

可以使用 /* 来指定参数类型,如下所示:

def f(pos1, pos2, /, pos_or_pwd, *, kwd1, kwd2): pass
# 此处 pos1和 pos2 仅限位置参数;pos_or_pwd 是位置或关键字参数;pwd1 和 pwd2 仅限关键字参数
可变参数 *args 和 ** kwargs
  • *args:可接受任意个位置参数,当调用函数时,所有未匹配的位置参数会在函数内打包为一个 tuple 对象,并赋值给变量 args
  • **kwargs:可接受任意个关键字参数,当调用函数时,所有未匹配的关键字参数会在函数内打包为一个 dict 对象,并赋值给变量 kwargs

变量的作用域

Python查找变量时按照“局部作用域”、“嵌套作用域”、“全局作用域”和“内置作用域”的顺序进行搜索

数据结构

列表 list [ ]

列表生成式 :用于生成列表,格式为 [for x in range(1, 20)]

生成器
  1. 为什么有生成器:生成器继承于迭代器,因此生成器拥有迭代器的所有特性。而列表和列表生成式中的数据都保存在内存中,当列表中的元素巨大时,将占用大量内存,从而导致内存溢出。
  2. 生成器是一个对象,没有保存列表中的数据,而是保存了产生元素的算法,同时记录游标的位置来确定当前输出到哪个元素了。每次调用都会返回一个元素,可以通过 next() 方法获取,这种方式既有列表的优势,又不占用空间。
  • 格式1 — 类似于列表生成式,将 [ ] 替换为 ( )
g = (x for x in range(1, 10))
print(type(g))   # <class 'generator'>
print(sys.getsizeof(g)) # 112
  • 格式2 — 使用 yield 关键字:函数包含了 yield 后便成为了生成器,当调用函数时不会执行内部代码,而是返回一个生成器对象。
 def test(number):
    a = 0
    b = 1
    n = 0
    while (n < number):
        yield b  
        a, b = b, (a+b)
        n += 1
# 此处 yield 关键字表示返回后面的变量b给生成器,而不是返回给函数。
g = test(10)  # 此时 g 便是一个生成器对象
  • 如何遍历生成器的元素:
    • next(生成器对象)
    • for循环:for val in g: print(val)
    • 生成器对象.next():内置的 __next__,当已经遍历到对象末尾时,会抛出StopIteration异常
  • 生成器对象的方法:
    • .close():关闭生成器
    • .send():和 next() 一样可以用来生成数据,但可以往生成器内部传递数据(可以和生成器内部进行交互)。执行next()和send()时都会在yield处暂停,并返回后边的值。使用send()前必须至少调用一次next()来生成一次数据(或是启动生成器),使生成器内部停留于yield处。而send()向生成器内部传递的数据将在yield处赋值,将传递进去的参数作为被挂起的yield语句的返回值,示例如下:
def writer():
    while True:
        data = yield
        print("data: ", data)
def producer():
    it = writer() # 返回生成器
    it.__next__()
    for i in range(5):
        print("send data: %d" %i)
        it.send("%d" %i)
producer()

数据类型可变性

  • 可变数据类型:list、set、dict
  • 不可变数据类型:number (int、float、bool)、string、tuple

python深拷贝与浅拷贝

赋值 =

赋值号 =:仅仅是原对象的一个引用

a = [1, 2, 3]
b = a
print(id(a), " ", id(b))
print("a is b ? ", a is b)
# 139708947438600   139708947438600
# a is b ?  True
浅拷贝

重新分配一块内存来创建一个新的对象,但存储的内容是原对象的各个子对象的引用。由此可以看出,当原对象的子对象是可变数据类型时,浅拷贝可能会出现问题。
浅拷贝实现方式:

  • 使用数据类型本身的构造器
  • 对于列表,还可以使用切片来实现
  • 使用 copy.copy() 函数,适用于任何数据类型(tuple除外)
# 1. 使用数据类型本身的构造器: list、set、dict 均适用
list1 = [1, 2, 3]
list2 = list(list1)
print(list2)
print("list1 is list2 ?",list1 is list2) 
print("list1==list2 ?",list1==list2)
#### 输出结果
[1, 2, 3]
list1 is list2 ? False # 分配了一块新内存,故与原对象的内存不同
list1==list2 ? True # 新内存存储的元素是原对象的子对象的引用

# 2. 对于列表,可以使用切片操作
list1 = [1, 2, 3]
list2 = list1[:]
print(list2)
print("list1 is list2 ?",list1 is list2)
print("list1==list2 ?",list1==list2)
#### 输出结果
[1, 2, 3]
list1 is list2 ? False
list1==list2 ? True

# 3. 使用 copy.copy() 函数,适用于任何数据类型
import copy
list1 = [1, 2, 3]
list2 = copy.copy(list1)
print(list2)
print("list1 is list2 ?",list1 is list2)
print("list1 == list2 ?",list1 == list2)
#### 输出结果
[1, 2, 3]
list1 is list2 ? False
list1==list2 ? True

# 4. 对于 元组tuple 和 字符串string,使用上述方法不会发生浅拷贝,而与赋值类似,开辟新的内存仅存储原对象的引用,
#   不是对原对象的各个子对象的引用,不属于浅拷贝。
tuple1 = (1, 2, 3)
tuple2 = tuple(tuple1)
print(tuple2)
print("tuple1 is tuple2 ?",tuple1 is tuple2)
print("tuple1 == tuple2 ?",tuple1 == tuple2)

tuple1 = (1, 2, 3)
tuple2 = tuple1[:]
print("tuple1 is tuple2 ?",tuple1 is tuple2)
print("tuple1 == tuple2 ?",tuple1 == tuple2)

tuple1 = (1, 2, 3)
tuple2 = copy.copy(tuple1)
print("tuple1 is tuple2 ?",tuple1 is tuple2)
print("tuple1 == tuple2 ?",tuple1 == tuple2)
#### 输出结果
(1, 2, 3)
tuple1 is tuple2 ? True
tuple1 == tuple2 ? True

# 5. 当浅拷贝时,如果原对象的元素是可变的,则可能会出现问题
list1 = [[1, 2], (30, 40)]
list2 = list(list1)
list1.append(100) # 对list1整体操作,不影响list2内部元素
print("list1:",list1)
print("list2:",list2)
list1[0].append(3) # 对list1内部元素操作,而操作对象[1, 2]是可变的,因此list2会受到影响
print("list1:",list1)
print("list2:",list2)
list1[1] += (50, 60) # 对list1内部元素操作,但操作对象(30, 40)是不可变的,因此list2不会受到影响
print("list1:",list1)
print("list2:",list2)
#### 输出结果
list1: [[1, 2], (30, 40), 100]
list2: [[1, 2], (30, 40)]
list1: [[1, 2, 3], (30, 40), 100]
list2: [[1, 2, 3], (30, 40)]
list1: [[1, 2, 3], (30, 40, 50, 60), 100]
list2: [[1, 2, 3], (30, 40)]
深拷贝

重新开辟一块内存,将原对象中各个子对象以递归的方式,通过创建新子对象来逐一拷贝到新内存中。新创建的对象与原对象无任何关联。
通常使用 copy.deepcopy() 函数实现

import copy
list1 = [[1, 2], (30, 40)]
list2 = copy.deepcopy(list1)

list1[0].append(3) # 对list1内部可变元素[1, 2]操作,但深拷贝下list2不会受到影响
print("list1:",list1)
print("list2:",list2)
#### 输出结果
list1: [[1, 2, 3], (30, 40)]
list2: [[1, 2], (30, 40)]

参考

位置参数和关键字参数
python 浅拷贝和深拷贝

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值