Python学习笔记(三)

一、元组(tuple)

       列表属于可变序列,可以任意修改列表中的元素。元组属于不可变序列,不能修改元组中的元素。因此,元组没有增加元素、修改元素、删除元素相关的方法。

       因此,我们只需要学习元组的创建和删除,元组中元素的访问和计数即可。元组支持如下操作:

1. 索引访问;

2. 切片操作;

3. 连接操作;

4. 成员关系操作;

5. 比较运算操作;

6. 计数:元组长度len()、最大值max()、最小值min()、求和sum()等。

1.1 元组的创建

1、通过()创建元组。小括号可以省略。

a = (10, 20, 30) 或者 a = 10, 20, 30

        如果元组只有一个元素,则必须后面加逗号。这是因为解释器会把(1)解释为整数1,(1,)解释为元组。

a = (1)

type(a)=<class 'int'>

a = (1,)   #或者 a=1,

type(a)=<class 'tuple'>

2、通过tuple()创建元组

tuple(可迭代的对象)

b = tuple()    #创建一个空元组对象

b = tuple("abc")

b = tuple(range(3))

b = tuple([2, 3, 4])

del b  #删除元组b

总结:

tuple()可以接收列表、字符串、其他序列类型、迭代器等生成元组。

list()可以接收元组、字符串、其他序列类型、迭代器生成列表。

1.2 元组的元素访问和计数

1、元组的元素不能修改

a = (20, 10, 30, 40)

a[3] = 40

2、元组的元素访问和列表一样,只不过返回的仍然是元组对象。

3、列表关于排序的方法list.sorted()是修改原列表对象,元组没有该方法。如果要对元组排序,只能使用内置函数sorted(tupleObj),并生成新的列表对象。

1.3 zip

zip(列表1、列表2,……)将多个列表对应位置的元素组合成为元组,并返回这个zip对象。

a = [1, 2, 3]

b = [40, 50, 60]

c = [11, 12, 13]

d = zip(a, b, c)

list(d) = [(1, 2, 3), (40, 50, 60), (11, 12, 13)]

1.4 生成器推导式创建元组

        从形式上看,生成器推导式与列表推导式类似,只是生成器推导式使用小括号。列表推导式直接生成列表对象,生成推导式生成的不是列表也不是元组,而是一个生成器对象。

       通过生成器对象,转化成列表或者元组。也可以使用生成器对象的_next_()方法进行遍历,或者直接作为迭代器对象来使用。不管用什么方式使用,元素访问结束后,如果需要重新访问其中的元素,必须重新创建该生成器对象。

s = (x*2 for x in range(5))

tuple(s) = (0, 2, 4, 6, 8)

list(s)= []   #只能访问一次元素。第二次就为空了,需要再生成一次。

s = (x*2 for x in range(5))

s.__next__() = 0   # 注意 这里是两个下划线

s.__next__() = 2

元组总结

1、元组的核心特点是:不可变序列;

2、元组的访问和处理速度比列表快;

3、与整数和字符串一样,元组可以作为字典的键,列表则永远不能作为字典的键使用。

二、字典

        字典是“键值对”的无序可变序列,字典中的每个元素都是一个“键值对”,包含:“键对象”和“值对象”。可以通过“键对象”实现快速获取、删除、更新对应“值对象”。

        列表中我们通过“下标数字”找到对应的对象。字典中通过“键对象”找到对应的“值对象”。“键”是任意的不可变数据,比如:整数、浮点数、字符串、元组。但是:列表、字典、集合这些可变对象,不能作为“键”。并且“键”不可重复。

        “值”可以是任意的数据,并且可重复。

一个典型的字典的定义方式:

      a = {'name':'carol','age':18,'job':'programmer'}

2.1 字典的创建

1、我们可以通过{}、dict()来创建字典对象。

a = {'name':'carol','age':18,'job':'programmer'}

b= dict('name'='carol','age'=18,'job'='programmer')

a = dict([("name","carol"),("age",18)])

c = {} #空的字典对象

d = dict() #空的字典对象

2、通过zip()创建字典对象

k = ['name','age','job']

v = ['carol',18,'student']

d = dict(zip(k,v))

d={'name': 'carol', 'age': 18, 'job': 'student'}

3、通过fromkeys创建值为空的字典

a = dict.fromkeys(['name','age','job'])

{'name': None, 'age': None, 'job': None}

2.2 字典元素的访问

1、通过 [键] 获得“值”。若键不存在,则抛出异常。

a = {'name':'carol','age':18,'job':'programmer'}

a['name']=carol

2、通过get()方法获得“值”。推荐使用。优点是:指定键不存在,返回None;也可以设定指定键不存在时默认返回的对象。推荐使用get()获取“值对象”。

a = {'name':'carol','age':18,'job':'programmer'}

a.get('name')=carol

3、列出所有的键值对

a = {'name':'carol','age':18,'job':'programmer'}

a.items=dict_items([('name','carol'),('age',18),('job','programmer')])

4、列出所有的键,列出所有的值

a = {'name':'carol','age':18,'job':'programmer'}

a.keys()=dict_keys(['name','age','job'])

a.values()=dict_values(['carol',18,'programmer'])

5. len() 键值对的个数

6. 检测一个“键”是否在字典中

a = {'name':'carol','age':18,'job':'programmer'}

“name” in a

True

2.3 字典元素添加、修改、删除

1、给字典新增“键值对”。如果“键”已经存在,则覆盖旧的键值对;如果“键”不存在,则新增“键值对”。

a = {'name':'carol','age':18,'job':'programmer'}

a['address']='西三旗1号院'

a['age']=16

2、使用update()将新字典中所有键值对全部添加到旧字典对象上。如果key有重复,则直接覆盖。

a = {'name':'carol','age':18,'job':'programmer'}

b={'name':'Betty','money':100,'sex':'女'}

a.update(b)

3、字典中元素的删除,可以使用del()方法;或者clear()

删除所有键值对;pop()删除指定键值对,并返回对应“值对象”;

a = {'name':'carol','age':18,'job':'programmer'}

del(a['name'])

b=a.pop('age') #从a中删除“age”键值对,并赋值给b。

a.clear() #调用clear就全部删除了a

4. popitem():随机删除和返回该键值对。字典是“无序可变序列”,因此没有第一个元素、最后一个元素的概念;popitem弹出随机的项,因为字典并没有“最后的元素”或者其他有关顺序的概念。若想一个接一个地移除并处理项,这个方法就非常有效(因为不用首先获取键的列表)。

a = {'name':'carol','age':18,'job':'programmer'}

a.popitem()

2.4 序列解包

1、序列解包可以用于元组、列表、字典。序列解包可以让我们方便的对多个变量赋值。

x,y,z=(20, 30, 10)

x=20     y=30    z=10

(a, b, c)=(9, 8, 10)

[a, b, c]=[10, 20, 30]

a=10     b=20

2、序列解包用于字典时,默认是对“键”进行操作;如果需要对键值对操作,则需要使用items()

;如果需要对“值”进行操作,则需要使用values()。

a={'name':'carol','age':18,'job':'programmer'}

x, y, z=a

x=name    y=age    z=job   #默认对键进行操作

x, y, z=a.items  #对键值进行操作

x, y, z=a.values  #对值进行操作

2.5 练习

r1={'name':'高小一', 'age':'18', 'salary':'30000', 'city':'北京'}

r2={'name':'高小二', 'age':'19', 'salary':'20000', 'city':'上海'}

r3={'name':'高小五', 'age':'20', 'salary':'10000', 'city':'深圳'}

tb = [r1, r2, r3]

#获得第二行人的薪资

print(tb[1].get("salary"))  #获得第二行人的薪资

# 打印表中所有人的薪资

for i in range(len(tb)):

    print(tb[i].get("salary"))

# 打印表中所有数据

for i in range(len(tb)):

    print(tb[i].get("name"), tb[i].get("age"),tb[i].get("salary"), tb[i].get("city"))

2.6 字典核心底层原理(重要)

        字典对象的核心是散列表。散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫做bucket。每个buccket有两部分:一个是键对象的引用,一个是值对象的引用。

        由于,所有bucket结构和大小一致,我们可以通过偏移量来读取指定bucket。

1、将一个键值对放进字典的底层过程

a{}

假设字典a对象创建完后,数组长度为8.

我们要把"name"="carol"这个键值对应放到字典对象a中,首先第一步需要计算键"name"的散列值。Python中可以通过hash()来计算。

bin(hash("name"))

0b11000001010000111000110110011000101011011101011101000111101001

由于数组长度为8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即“001”,十进制是数字1。我们查看偏移量1,对应的bucket是否为空。如果为空,则将键值对放进去。如果不为空,则依次取右边3位作为偏移量,即“101”,十进制是数字5。再查看偏移量为5的bucket是否为空。直到找到为空的bucket将键值放进去。

流程如下:

2、扩容

        python会根据散列表的拥挤程度扩容。“扩容”指的是:创造更大的数组,将原有内容拷贝到新的数组中。接近2/3/时,数组就会扩容。

3、根据键查找“键值对”的底层过程

a.get("name")

'carol'

当我们调用a.get("name"),就是根据键“name”查找到“键值对”,从而找到值对象“carol”。

第一步,我们仍然要计算“name”对象的散列值:

bin(hash("name"))

0b11000001010000111000110110011000101011011101011101000111101001

和存储的底层流程算法一致,也是依次取散列值的不同位置的数字。假设数组长度为8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即“001”,十进制是数字1。我们查看偏移量1,对应的bucket是否为空。如果为空,则返回None。如果不为空,则将这个bucket的键对象计算对应散列值,和我们的散列值进行比较,如果相等,则将对应“值对象”返回。如果不相等,则再依次取其他几位数字,重新计算偏移量。依次取完后,仍然没有找到,则返回None。流程如下:

用法总结:

1、键必须可散列:

(1)数字、字符串、元组,都是可散列的。

(2)自定义对象需要支持下面三点:

         ① 支持hash()函数;

         ② 支持通过__eq__()方法检测相等性;

         ③ 若a==b为真,则hash(a)==hash(b)也为真。

2、字典在内存中开销巨大,典型的空间换时间。

3、键查询速度很快。

4、往字典里面添加新建可能导致扩容,导致散列表中键的次序变化。因此,不要在遍历字典的同时进行字典的修改。

三、集合

集合是无序可变,元素不能重复。实际上,集合底层是字典实现,集合的所有元素都是字典中的“键对象”,因此是不能重复的且唯一的。

3.1 集合创建和删除

1、使用{}创建集合对象,并使用add()方法添加元素。

a={3, 5, 7}

a.add(9)

a={9, 3, 5, 7}

2、使用set(),将列表、元组等可迭代对象转成集合。如果原来数据存在重复数据,则只保留一个。

a=['a', 'b', 'c', 'b']

b=set(a)

b={'b', 'a', 'c'}

3、remove()删除指定元素;clear()清空整个集合

a={10, 20, 30, 40, 50}

a.remove(20)

3.2 集合相关操作

像数学中概念一样,python对集合也提供了并集、交集、差集等运算。

a = {1, 3, 'sxt'}

b = {'he', 'it', 'sxt'}

a|b     #并集

{1, 3, 'sxt','he', 'it' }

a&b    #交集

{'sxt'}

a-b    #差集

{1, 3}

a.union(b)    #并集

{1, 3, 'sxt','he', 'it' }

a.intersection(b)    #交集

{'sxt'}

a.difference(b)    #差集

{1, 3}

四、控制语句

        前面学习的变量、数据类型(整数、浮点数、布尔)、序列(字符串、列表、元组、字典、集合),可以看做是数据的组织方式。数据可以看做是“砖块”。

        流程控制语句是代码的组织方式,可以看做是“混凝土”。

        一个完整的程序,离不开“砖块”,也离不开“混凝土”。他们的组合,才能让我们建立从小到“一个方法”,大到“操作系统”,这样各种各样的“软件”。

PyCharm开发环境的使用

集成开发环境【IDE】:PyCharm、IDLE、wingIDE、Eclipse、IPython

下载地址:Download PyCharm: The Python IDE for data science and web development by JetBrains

4.1 选择结构

        选择结构通过判断条件是否成立,来决定执行哪个分支。选择结构有多种形式,分为:单分支、双分支、多分支。流程图如下:

4.1.1 单分支选择结构

if 语句单分支结构的语法形式如下:

if 条件表达式:

       语句/语句块

其中:

① 条件表达式:可以是逻辑表达式、关系表达式、算术表达式等等。

② 语句/语句块:可以是一条语句,也可以是多条语句。多条语句,缩进必须对齐一致。

【操作】输入一个数字,小于10,则打印这个数字。

num = input("输入一个数字:")

if int(num)<10:

        print(num)

4.1.2 条件表达式详解

在选择和循环结构中,条件表达式的值为False的情况如下:

        False、0、0.0、空值None、空序列对象(空列表、空元组、空集合、空字典、空字符串)、空range对象、空迭代对象。

        其他情况,均为True。Python所有的合法表达式都可以看做条件表达式,甚至包括函数调用的表达式。

【操作】测试各种条件表达式

if 3:    #整数作为条件表达式
    print("ok")
a=[]     #列表作为条件表达式,由于为空列表,是False
if a:
    print("空列表,False")
s="False" #非空字符串,是True
if s:
    print("非空字符串,是True")
c=9
if 3<c<20:
    print("3<c<20")
if 3<c and c<20:
    print("3<c and c<20")
if True:     #布尔值
    print("True")

4.1.3 条件表达式中,不能有赋值操作符“=”

在python中,条件表达式不能出现赋值操作符“=”,避免了其他语言中经常误将关系运算符“==”写作赋值运算符“=”带来的困扰。如下代码将会报语法错误:

if 3<c and (c=20):
    print("赋值符不能出现在条件表达式中")

4.2 双分支选择结构

双分支结构的语法格式如下:

条件表达式:

        语句1/语句块1

else:

        语句2/语句块2

【操作】输入一个数字,小于10,则打印该数字;大于10,则打印“数字太大”

num = input("输入一个数字:")
if int(num)<10:
    print(num)
else:
    print("数字太大")

4.2.1 三元条件运算符

python提供了三元运算符,用来在某些简单双分支赋值情况。三元条件运算符语法格式如下:

条件为真时的值    if    (条件表达式)    else    条件为假时的值

【操作】上一个案例代码,可以用三元条件运算符实现:

num = input("输入一个数字:")
print(num if int(num)<10 else "数字太大")

可以看到,这种写法更加简洁、易读。

4.3 多分支选择结构

多分支选择结构的语法格式如下:

if 条件表达式1:

        语句1/语句块1

elif 条件表达式2:

        语句2/语句块2

……

elif 条件表达式n:

        语句n/语句块n

[else:

        语句n+1/语句块n+1

]

【注】计算机行业,描述语法格式时,使用中括号[]通常表示可选,非必选。

多分支结构,几个分支之间是有逻辑关系的,不能随意颠倒顺序。

【操作】输入一个学生的成绩,将其转化成简单描述:不及格(<60)、及格(60-79)、良好(80-89)、优秀(90-100)

方法一:(利用完整的条件表达)

score = int(input("请输入分数:"))
grade=""
if (score<60):
    grade="不及格"
if(60<=score<80):
    grade = "及格"
if(80<=score<90):
    grade = "良好"
if(90<=score<=100):
    grade = "优秀"
print("分数是{0}, 等级是{1}".format(score,grade))

每个分支都使用了独立的、完整的判断,顺序可以随意挪动,而不影响程序运行。

方法二:

score = int(input("请输入分数:"))
grade=""
if (score<60):
    grade="不及格"
elif score<80:   #60-80之间
    grade = "及格"
elif score<90:
    grade = "良好"
else:
    grade = "优秀"
print("分数是{0}, 等级是{1}".format(score,grade))

多分支结构,几个分支之间是有逻辑关系的,不能随意颠倒顺序。

【操作】已知点的坐标(x, y),判断其所在的象限。

x = int(input("请输入x轴坐标:"))
y = int(input("请输入y轴坐标:"))
a =""
if (x==0 and y==0):
    a = "原点"
elif (x==0):
    a = "y轴"
elif y==0:
    a = "x轴"
elif x>0 and y>0:
    a = "第一象限"
elif x<0 and y>0:
    a = "第二象限"
elif x<0 and y<0:
    a = "第三象限"
else:
    a = "第四象限"
print("坐标点({0},{1}), 位于{2}".format(x,y,a))

4.4 选择结构嵌套

选择结构可以嵌套,使用时一定要注意控制好不同级别代码块的缩进量,因为缩进量决定了代码的从属关系。语法格式如下:

if 表达式1:

        语句块1

        if 表达式2:

                语句块2

        else:

                语句块3

else:

        if 表达式4:

                语句块4

【操作】输入一个分数。分数在0-100之间。90以上是A,80以上是B,70以上是C,60以上是D。60以下是E。

方法一:

score = int(input("请输入一个分数:"))
if (score>=0 and score<=100):
    if score>=90:
        print("A")
    elif score>=80:
        print("B")
    elif score>=70:
        print("C")
    elif score>=60:
        print("D")
    else:
        print("E")
else:
   print("输入分数错误")

方法二:

score = int(input("请输入一个分数:"))
degree = "ABCED"
num = 0
if (score>100 or score<0):
    print("输入分数错误,请输入一个0-100的分数")
else:
    num = score//10
    if num<6:
        num=5
    print(degree[9-num])

五、循环结构

循环结构用来重复执行一条或多条语句。表达这样的逻辑:如果符合条件,则反复执行循环体里的语句。在每次执行完后都会判断一次条件是否为True,如果为True则重复执行循环体里的语句。如图所示:

循环体里面的语句至少应该包含改变条件表达式的语句,以使循环趋于结束;否则,就会变成一个死循环。

5.1 while循环

while 循环的语法格式如下:

while 条件表达式:

       循环体语句

【操作】利用while循环打印从0-10数字

num = 0
while num <= 10:
    print(num, end="\t")
    num += 1

【注】end="\t",表示不换行。

【操作】利用while循环,计算1-100之间数字的累加和;计算1-100之间偶数的累加和,计算1-100之间奇数的累加和。

num = 0
sum_all = 0      #1-100所有数的累加和
sum_even = 0     #1-100偶数的累加和
sum_odd = 0      #1-100奇数的累加和
while num <=100:
    sum_all += num
    if num%2 == 0:
        sum_even += num
    else:
        sum_odd +=num
    num += 1     #迭代,改变条件表达式,使循环趋于结束
print("1-100所有数的累加和", sum_all)
print("1-100偶数的累加和", sum_even)
print("1-100奇数的累加和", sum_odd)

5.2 for循环和可迭代对象遍历

for 循环通常用于可迭代对象的遍历。for 循环的语法格式如下:

for    变量    in    可迭代对象:

        循环体语句

【操作】遍历一个元组或列表

for x in (20, 30, 40):
    print(x*3, end="\t")

5.3 可迭代对象

python包含以下几种可迭代对象:

1、序列。包含:字符串、列表、元组

2、字典

3、迭代器对象(iterator)

4、生成器函数(generator)

5、文件对象

【操作】遍历字符串中的字符

for x in list("carol007"):
    print(x, end="\t")

【操作】遍历字典

a = {'name':'carol','age':18,'job':'programmer'}
for x in a:     # 遍历字典所有的key
    print(x, end="\t")
for x in a.keys():     # 遍历字典所有的key
    print(x, end="\t")
for x in a.values():     # 遍历字典所有的value
    print(x, end="\t")
for x in a.items():     # 遍历字典所有的“键值对”
    print(x, end="\t")

5.4 range对象

rangez对象是一个迭代器对象,用来产生指定范围的数字序列。格式为:

range(start, end, [,step])

生成的数值序列从start开始到end结束(不包含end)。若没有填写start,则默认从0开始。step是可选的步长,默认为1。如下是几种典型示例:

for i in range(10)        产生序列:0  1  2  3  4  5  6  7  8  9

for i in range(3, 10)    产生序列:3  4  5  6  7  8  9

for i in range(3, 10, 2)产生序列:3  5  7  9

【操作】利用for 循环,计算1-100之间数字的累加和;计算1-100之间偶数的累加和;计算1-100之间奇数的累加和。

num = 0
sum_all = 0      #1-100所有数的累加和
sum_even = 0     #1-100偶数的累加和
sum_odd = 0      #1-100奇数的累加和
for i in range(101):
    sum_all = sum_all+ num
    if i%2==1:
        sum_odd += i
    else:
        sum_even += i
print("1-100所有数的累加和", sum_all)
print("1-100偶数的累加和", sum_even)
print("1-100奇数的累加和", sum_odd)

5.5 嵌套循环

一个循环体内可以嵌入另一个循环体,一般称为“嵌套循环”,或者“多重循环”。

【操作】打印如下图案:

0 0 0 0 0 

1 1 1 1 1

2 2 2 2 2

3 3 3 3 3

4 4 4 4 4

for x in range(5):
    for y in range(5):
        print(x, end="\t")
    print()    # 起到换行的作用

【操作】利用嵌套循环打印九九乘法表

for x in range(1,10):
    for y in range(1,x+1):
        print("{0}*{1}={2}".format(x, y, x*y ), end="\t")
    print()

【操作】用列表和字典存储下表信息,并打印出表中高于15000的数据

tb = []
r1 =dict(name="高小一", age=18, salary=30000, city="北京")
r2 = dict(name="高小二", age=19, salary=20000, city="上海")
r3 = dict(name="高小五", age=20, salary=10000, city="深圳")
tb = [r1, r2, r3]
for i in tb:
    if i.get("salary")>15000:
        print(i)

5.6 break 语句

break语句可用于while和for循环,用来结束整个循环。当有嵌套循环时,break语句只能挑出最近一层的循环。

【操作】使用break语句结束循环

while True:
    a = input("请输入一个字符(输入Q或q结束)")
    if a=='Q' or a=='q':
        print("循环结束,退出")
        break
    else:
        print(a)

5.7 continue语句

continue语句用于结束本次循环,继续下一次。多个循环嵌套时,continue也是应用于最近的一层循环。

【操作】要求输入员工的薪资,若薪资小于0则重新输入。最后打印出录入员工的数量和薪资明细,以及平均薪资。

empNum = 0
salarySum = 0
salarys = []
while True:
    s = input("请输入员工的薪资(按Q或q结束)")
    if s.upper()=='Q':
        print("录入完成,退出")
        break
    if float(s)<0:
        continue
    empNum +=1
    salarys.append(float(s))
    salarySum += float(s)

print("员工人数{0}".format(empNum))
print("录入薪资:", salarys)
print("平均薪资{0}".format(salarySum/empNum))

5.8 else 语句

while、for循环可以附带一个else语句(可选)。如果for、while语句没有被break语句结束,则会执行else子句,否则不执行。语法格式如下:

while 条件表达式:

        循环体

else:

        语句块

或者:

for 变量 in 可迭代对象:

        循环体

else:

        语句块

5.9 循环代码优化

虽然计算机越来越快,空间越来越大,我们仍然要在性能问题上“斤斤计较”。编写循环时,遵守下面三个原则可以大大提高运行效率,避免不必要的低效计算:

1、尽量减少循内部不必要的计算

2、嵌套循环中,尽量减少内层循环的计算,即可能向外提。

3、局部变量查询较快,尽量使用局部变量。

【循环代码优化测试】

import time
start = time.time()
for i in range(1000):
    result = []
    for m in range(10000):
        result.append(i*1000+m*100)

end = time.time()
print("耗时:{0}".format((end-start)))

start2 = time.time()
for i in range(1000):
    result = []
    c = i*1000    # 优化的点在这里
    for m in range(10000):
        result.append(c+m*100)

end2 = time.time()
print("耗时:{0}".format((end2-start2)))

5.10 其他优化手段:

1、连接多个字符串,使用join()而不使用+

2、列表进行元素插入和删除,尽量在列表尾部操作。

5.11 使用zip()并行迭代

通过zip()函数对多个序列进行并行迭代,zip()函数在最短序列“用完”时就会停止。

【操作】测试zip()并行迭代

names =("carol", "Betty","一","二")
ages = (18, 16, 20, 25)
jobs = ("老师", "程序员", "公务员", "学生" )

for name,age,job in zip(names, ages, jobs):
    print("{0}--{1}--{2}".format(name, age, job))

for i in range(4):
    print("{0}--{1}--{2}".format(names[i], ages[i], jobs[i]))

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值