文章目录
输入输出
输出
在控制台输出可以使用print函数,如:
print("hello")
# 也可以用单引号标识字符串
print('hello')
# 每个参数会通过空格连接起来
print("hello", "world")
# 使用\n转义符换行
print("hello,\nworld")
# 使用r''避免转义
print(r"hello,\nworld")
# 多行文本也可以使用'''
print('''1
2
3''')
# r对'''也有效
print(r'''1\n
2
3''')
输入
要读取用户输入可以使用input函数
name = input()
# 带提示语
name = input("Please enter value: ")
需要注意input读取的是字符串,如果要转换为数字,可以用int函数
bir = int(input('birth: '))
数据类型及变量
数据类型
数据类型分为以下几种:
- 整数
- 可以用_分隔,提高可读性
- 也可以用16进制标识,前面加0x
- 浮点数
- 字符串
- 可以用单引号也可以用双引号
- 引号前面加r表示引号内的特殊字符不进行转义
- 用3个单引号可以表示多行内容,如’‘’…‘’’
- 布尔值
- 只有True或False两种值
- 可以用and、or、not进行运算
- 空值
- None,和Java的Null是一个意思
变量
- 变量名必须要是大小写英文、数字和_组合,且不能用数字开头
- 变量可以是任意数据类型,根据值推断,不用显示声明,如a=1,a就是一个数字
- 同一个变量可以反复赋值不同的数据类型值
常量
常量全部用大写字母表示,只是习惯用法,Python并不会保证一定不会改变它。如PI=3.14159
除法
- /:计算结果是浮点数,即使两个整数恰好整除除,得到的也是浮点数,如9/3=3.0
- //:整数相除得到的都是整数,只取整数部分(向下取整),如10//3=3
字符串和编码
编码概念
计算机只能处理数字,文本也会转换为数字,最早只有127个字符被编码到计算机里,即ASCII编码,只能存储一个字节,所以后面又出现了Unicode和UTF-8这样的字符集,Unicode包含了ASCII编码,通常是两个字节。若全部是英文,用Unicode存储就比较浪费空间,因此出现UTF-8,根据Unicode字符大小编码成1-6个字节,在内存中使用Unicode,而要保存到硬盘或进行传输时,就转换为UTF-8编码。
字符串与编码
- 在Python3中,字符串是以Unicode编码的
- 字符与编码转换函数
- ord:获取字符的整数表示形式
- chr:获取数字对应的字符
- x='ABC’和x=b’ABC’区别:
- 前者是以Unicode表示的,一个字符对应若干个字节
- 后者是以字节为单位的bytes,一个字符对应一个字节,需注意引号中只能是ASCII字符
- len函数计算字符串的字符数,若是bytes,则计算的是字节数
- 编解码
- ‘中文’.encode(‘utf-8’)
- b’中文’.decode(‘utf-8’),如果中间有无效字符,则会报错,b’中文’.decode(‘utf-8’, errors=‘ignore’)可以忽略
字符串
- 注释:通常会在py文件头写上如下两行
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
第一行是告诉Linux系统,这是Python可执行程序,Windows会忽略该注释;第二行是告诉Python解释器,按照UTF-8编码读取源码,否则在源代码中写的中文输出可能会有乱码,同时文件编辑器也要设置UTF-8才行。
2. 格式化,有%、format和f-string三种格式化方法
a. 使用%格式化
- %s:字符串占位符
- %d:整数占位符
- %f:浮点数占位符
- %x:16进制整数占位符
- %%:转义,标识普通的%
'Hello, %s' % 'world'
'Hi, %s! you have $%d.' % ('Darker', 1000)
只有一个参数的时候括号是可以省略的,%d和%f可以指定是否补0和小数位数,如%2d(前面补两个空格)、%02d(前面补两个0)、%.2f(小数位数指定为2位,注意是四舍五入)
b. 使用format格式化
'Hello,{0},成绩提升了{1:.1f}%'.fromat('Darker', 17.125) // Hello,Darker,成绩提升了17.1%
c. f-string
r = 2.5
s = 3.14
print(f'The area of a circle with radius {r} is {s:.2f}')
- 切片操作与list相同,结果仍然是字符串
print("前3个字符", "abcdefghijklmnopq"[:3])
需要注意format和f-string对小数采用的是银行家舍入规则(前一位是奇数则进一位,后一位是偶数则舍去),%采用的是四舍五入
list和tuple
list
基本操作
# 创建list
arr = ['a', 'b', 'c']
print(arr)
arr1 = ['a', 1, ['b', 2]]
print(arr1)
# 获取列表长度
print(len(arr))
# 列表元素正向读取
print(arr[0])
print(arr[1])
print(arr[2])
# 列表元素逆向读取
print(arr[-1]) // c
print(arr[-2]) // b
print(arr[-3]) // a
# 插入元素
arr.insert(1, 'f')
print(arr) // ['a', 'f', 'b', 'c']
# 追加元素
arr.append('e') // ['a', 'f', 'b', 'c', 'e']
print(arr)
# 移除最后一个和指定索引位的元素
print(arr.pop())
print(arr.pop(1))
print(arr)
# 替换元素
arr[1] = 'd'
print(arr)
print("切片操作")
l = list(range(100))
print("取前10个数:", l[:10])
print("取11-20:", l[11:20])
print("取后10个数:", l[-10:])
print("前10个数,每2个取一个:", l[:10:2])
print("所有数,每5个取一个:", l[::5])
print("复制一个list:", l[:])
列表生成式
print("列表推导式")
print("前10个数的平方:", [x * x for x in range(10)])
print("if放在后面是过滤,不能加else:", [x * x for x in range(10) if x % 2 == 0])
print("if放在前面是表达式,必须加else:", [x if x % 2 == 0 else -x for x in range(10)])
print("两层循环生成全排列:", [m + n for m in 'abc' for n in 'xyz'])
import os
print("指定目录下的文件及目录:", [d for d in os.listdir('e:\\')])
tuple
不可变的list,除了不能改变元素外其它操作和list都一样
arr = ('a', 'b', 'c')
print(arr)
# 创建只有一个元素的tuple必须加逗号,不然python会把括号当成是数学运算符
arr1 = ('a',)
print(arr1)
# 可变的tuple
arr2 = ('a', 'b', [1, 2])
arr2[2].append(3)
print(arr2)
print("切片操作与list相同,结果仍然是tuple")
tun = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
print("前5个:", tun[0:5])
生成器
生成器可以用于惰性求值的场景,一边循环一边创建,避免一次创建浪费内存。
列表的生成器模式
将列表生成式外面的[]改为()即生成器,可以用next函数或迭代器获取元素,当使用next函数获取到最后没有值时,会报StopIteration错。
g = (x for x in range(10))
print(g) # <generator object <genexpr> at 0x000001FF2ACB4880>
print(next(g)) # 0
print(next(g)) # 1
print(next(g)) # 2
print("迭代器获取")
for i in g:
print(i)
print(next(g)) # StopIteration
生成器函数
还可以创建生成器函数,当一个 函数中包含yield关键字,那这个函数就是一个generator函数,调用一个generator函数将返回一个generator:
def add():
print("step 1")
yield 1
print("step 2")
yield 3
print("step 3")
yield 5
a = add()
print(next(a)) # 1
print(next(a)) # 3
print(next(a)) # 5
# 需注意每次调用add()都会生成一个独立的生成器对象,所以都会从头开始
print(next(add())) # 1
print(next(add())) # 1
print(next(add())) # 1
# 但是在迭代器中不会重头开始
for i in add():
print(i)
yield的作用就是在调用next函数后遇到yield就会中断,下次调用会从中断的地方开始继续。
# 斐波拉契数列
def fib(max):
n, a, b = 0, 0, 1
while n < max:
n += 1
yield b
a, b = b, a + b
print("fib(10)", [i for i in fib(10)])
# 杨辉三角
def triangles(n):
row = [1]
j = 0
while j < n:
j += 1
yield row
row = [1] + [row[i] + row[i + 1] for i in range(len(row) - 1)] + [1]
for i in triangles(10):
print(i)
Iterator与Iterable
可以直接用用for循环的对象统称为可迭代对象Iterable:list、tuple、dict、set、str及生成器。
可以被next()函数调用并不断返回下一个值得对象称为迭代器Iterator。
条件判断
if
基本语法如下:
a = 10
if a > 10:
print("a is greater than 10")
elif a > 5:
print("a is greater than 5 but not greater than 10")
else:
print("a is not greater than 5")
非0、None、空字符串和空列表时可以简写
b = 0
if b:
print("b is true: %d" % b)
b = 1
if b:
print("b is true: %d" % b)
b = None
if b:
print("b is true: %s" % b)
b = 'a'
if b:
print("b is true: %s" % b)
b = ''
if b:
print("b is true: %s" % b)
b = []
if b:
print("b is true: %s" % b)
b = ['a']
if b:
print("b is true: %s" % b)
模式匹配
基本语法如下:
score = 'B'
match score:
case 'A':
print("A")
case 'B':
print("B")
case 'C':
print("C")
case 'D':
print("D")
case 'F':
print("F")
case _:
print("Unknown")
还可以匹配多个值、匹配一定范围以及在case中声明变量:
age = 15
match age:
case x if x < 10:
print("Age is less than 10")
case 10:
print("Age is 10")
case 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18:
print("Age is between 10 and 18")
case 19:
print("Age is 19")
case _:
print("Age is unknown")
匹配列表:
args = ['gcc', 'hello.c', 'world.c']
# args = ['clean']
# args = ['gcc']
match args:
# 如果仅出现gcc,报错:
case ['gcc']:
print('gcc: missing source file(s).')
# 出现gcc,且至少指定了一个文件:
case ['gcc', file1, *files]:
print('gcc compile: ' + file1 + ', ' + ', '.join(files))
# 仅出现clean:
case ['clean']:
print('clean')
case _:
print('invalid command.')
循环
for in
arr = ['a', 1, [1, 'b']]
for i in arr:
print(i)
# 使用range快速生成整数序列并求和
sum = 0
for i in range(101):
sum += i
print(sum)
# 同时遍历多个元素
for i, j, k in [(1, 2, 3), (3, 4, 5), (5, 6, 7)]:
print(i, j, k)
# 遍历字典
d = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
print("遍历key")
for key in d:
print(key)
print("遍历value")
for value in d.values():
print(value)
print("遍历key和value")
for key, value in d.items():
print(key, value)
# 遍历字符串
s = 'abcdefg'
for ch in s:
print(ch)
如何判断是否是可迭代对象?
- 先导入包:from collections.abc import Iterable
- 使用isinstance判断
# 判断是否是可迭代对象
from collections.abc import Iterable
print(isinstance([1, 2, 3], Iterable))
print(isinstance("abc", Iterable))
list如何使用下标索引?
- 需要使用enumerate函数将list变为元素对
for i, value in enumerate(['a', 'b', 'c']):
print(i, value)
while
# while循环
sum1 = 0
n = 100
while n > 0:
sum1 += n
n -= 1
print(sum1)
# break跳出循环
n = 10
while n > 0:
if n < 8:
print('n is less than 8')
break
print(n)
n -= 1
# continue跳过本次循环
n = 10
while n > 0:
if n == 8:
print('n == 8')
n -= 1
continue
print(n)
n -= 1
break和contine也可以用于for in循环中
dict和set
dict
d = {'a': 1, 'b': 2}
print(d)
# 放入元素
d['c'] = 3
print(d)
# 放入重复元素会覆盖旧元素
d['c'] = 4
print(d)
# 读取元素
print(d['a']) # 读取不存在的元素会报错d['e']
print(d.get('b'))
print(d.get('e')) # 返回None
print(d.get('e', -2)) # 不存在时返回-2
# 删除元素
d.pop('a')
print(d)
set
# 创建set
s = {1, 2, 'a'}
print(s)
s = set(['a', 'b', 1, 1])
print(s)
# 添加元素
s.add(2)
print(s)
# 删除元素
s.remove(2)
print(s)
# 交集并集
s1 = {1, 'c', 4, 'a'}
print(s & s1)
print(s | s1)
注意点:
- dict的key和set的元素都必须是不可变对象(string、数字)
- 放入的顺序并不是最终的存储顺序
函数
函数定义
def add(x, y):
return x + y
通过def定义函数,当没有返回值时,可以return None,也可以简写为return。
当想要定义一个空函数时,可以在函数体中用pass作占位符,避免报语法错误:
def get():
pass
python的函数还支持返回多个值(通过结果可以发现实际上时返回一个tuple):
def multiReturn(x, y):
return x + y, x - y
a, b = multiReturn(3, 2)
print(a, b) # 5 1
c = multiReturn(2, 1)
print(c) # (3, 1)
参数
默认参数
def add1(a, b = 1, c = 2, d = 3):
return a + b + c + d
print(add1(5))
print(add1(5, c = 4))
函数的参数可以指定默认值,当不传时使用默认值,当不按顺序提供默认值时需要指定参数名称。
需注意默认参数只能定义在必选参数后面,同时需要尤其注意默认参数不能为可变对象,否则会出现意料之外的错误。
def appendEnd(L = []):
L.append('END')
return L
print(appendEnd()) # ['END']
print(appendEnd()) # ['END', 'END']
可变参数
def add2(*a):
sum = 0
for i in a:
sum += i
return sum
print(add2(1, 2, 3))
在参数前面加上*号表示可变参数,函数内部接收到的是一个tuple,可以传入任意个参数。
当已经有一个list或者tuple参数,而函数定义的可变参数时,可以按下面的方式传入:
arr = [1, 2, 3, 4]
print(add2(*arr))
关键字参数
键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict:
def person(name, age, **other):
print('name:', name, 'age:', age, 'other', other)
person('darker', 20) # name: darker age: 20 other {}
person('darker', 20, city = 'beijing') # name: darker age: 20 other {'city': 'beijing'}
# 使用**可以直接传入一个已经存在的dict,传入的是拷贝,函数内部的修改对函数的dict没有影响
darkerOhter = {'gender': 'man', 'city': 'beijing'}
person('darker', 20, **darkerOhter) # name: darker age: 20 other {'gender': 'man', 'city': 'beijing'}
可以限制关键字参数只接收哪些参数:
def person1(name, age, *, city):
print('name:', name, 'age:', age, 'city:', city)
person1('darker', 20, city='beijing')
person1('darker', 20, gender='man') # 报错
如果已经有可变参数了,则后面的命名关键字参数就不再需要一个特殊分隔符了:
def person2(name, age, *args, city):
print('name:', name, 'age:', age, 'args:', args, 'city:', city)
person2('darker', 31, 'man', city='beijing') # name: darker age: 31 args: ('man',) city: beijing