跳转至

Class 2

课前预习

预习思考题

  1. 计算机系统由哪五部分组成?
    • CPU, 内存, 外部设备, 系统软件, 应用软件
  2. 计算机的存储模式和存储容量是怎样表示的?它们的关系如何?(信息最小单位为位、处理和存储信息的最小单位为字节)
    • 存储模式:大端序小端序
    • bit和byte
  3. 地址编号从A至B,它占C个字节。告知A、B、C中任意二个,如何计算第三个?
    • 对于一个64位系统\(C = B - A + 1\)
  4. 十进制和二进制、八进制、十六进制怎样相互转换?
    • 十进制转成后面等进制都是先转成二进制,对于八进制是每三位二进制对应八进制的一位,每四位二进制对应十六进制的一位
    • 反之,它们转成十进制就很简单,每一位\(\times\)进制数的\(k-1\)次方
  5. 原码、反码、补码的定义及它们如何相互转换?
    • 正数:符号位为0,三种都一样
    • 负数:符号位是1,原码和正数一样,反码是除了符号位0变1,1变0,补码是反码+1

1. 数字类型

  • 计算机内部用位序列表示数据,类型为这些位序列赋予了意义。同时,类型限制了数据的范围意义。
    • 整数
    • 浮点数
    • 复数

整数

1
2
3
4
5
6
7
8
>>>66
   66
>>>-175
   -175
>>>07
   SyntaxError: invalid token #注意到07是无效的整数
>>>0
   0

二进制,八进制和十六进制

  • 0b或0B 代表二进制
  • 0o或0O 代表八进制
  • 0x或0X 代表十六进制
    1
    2
    3
    4
    5
    6
    >>>0b10
        2
    >>>0o10
       8
    >>>0x10
       16
    

整数可以表示很大的数

1
2
3
>>>google=10**50
>>>google
100000000000000000000000000000000000000000000000000

运算符

  • 与之前学过的C相比,注意几个特殊运算符:
    • 浮点数除法:/
    • 整除:// (永远往小了取)
    • 幂:**

浮点数

  1. 浮点数也是小数:
    • 1.23, 3.14, -9.01
  2. 科学计数法:
    • \(1.23\times 10^9\)就是\(1.23e9\)
    • 0.000012可以写成\(1.2e-5\)
    • "e"的前后都不能空,"e"的后面要整数

浮点数运算注意事项

  • 浮点数运算有误差
  • py >>>2.1-2.0==0.1 False >>>3.8/0.7 5.428571428571429
  • 浮点数的整除还是浮点数(整浮点数)
  • py >>>3.8//0.7 5.0 >>>3.8%0.7 0.30000000000000004

复数

  1. 所谓复数,就是由实部和虚部两部分组成的数,虚部用\(j\)表示
  2. real方法取实部,imag方法取虚部,complex()函数用于创建一个值为real + imag*j的复数

数学库(math)

  1. math库是一个数学库,包含了很多的数学常数和数学函数
  2. 要使用math库,要先用"import math"语句引入math库
    • py >>>import math >>>math.pi 3.141592653589793 >>>math.sqrt(9) 3.0

思考题

print(2.1-2.0==0.1)
print(2.5-2.0==0.5)
- 试问这两行结果分别是多少:False和True - 原因:0.1在二进制体系里面会被拦腰斩断

函数和方法

  1. 方法是与数据对象关联的函数,是在相对应数据对象名字空间中定义的函数
  2. 用”.”记法调用的函数也称方法
    • math.cos(5)
    • cos()是函数,cos()也称为math对象的方法

2. 字符串

  • 字符串是以''或""括起来的任意文本,比如'abc',"xyz"等等。请注意,''或""本身只是一种表示方式,不是字符串的一部分

多行字符串

  • 可以用""内的'\n'来表示多行注解

转义字符

转义字符 描述
\ \
\' '
\" "
\a 响铃
\b 退格
\n 换行
\t 横向制表符
\r 回车
\f 换页
\ooo 最多三位八进制数
\xyy 两位十六进制数

转义字符举例

字符串运算符: +, *

1
2
3
4
5
6
7
8
9
>>>"人生苦短"+" 我用Python"
'人生苦短 我用Python'
>>>'2'*3
'2'
# type函数是一个内置的函数,调用它就能知道想要查询对象的类型信息
>>>type(1)
<class 'int'>
>>>type("python")
<class 'str'>

3. 布尔类型、空类型和列表

  1. 布尔类型的变量只有True、False两种值,要么是True,要么是False(请注意大小写)
  2. 布尔值可通过逻辑运算符和关系运算符计算出来。关系运算符是 <、 <=、 >、 >=、==和!=, 逻辑运算符是and、or和not。

逻辑运算规则

  • 逻辑运算的对象可以是任意类型
  • False、None、整数0、浮点数0.0、空字符串(“”) 以及空的容器类型等对象都作为假,其它都作为真。
  • not exp 【exp代表一个表达式】
    • 若exp值为真,则结果为False;否则结果为True。
  • exp1 and exp2
    • 若exp1值为真,则结果为exp2的值;
    • 若exp1值为假,则结果为exp1的值,且不计算exp2。
  • exp1 or exp2
    • 若exp1值为真,则结果为exp1的值,且不计算exp2;
    • 若exp1值为假,则结果为exp2的值。

注意

  • 注意一种会报错的情况,>>>'Hello'>3
    • 此时结果会显示TypeError: unorderable types: str()>int()

空类型

  1. 如把类型用集合表示表示:

    • datatype = {整数, 浮点数,复数,字符, ...}
    • datatype的幂集: {{}, {}, {}, ...}
    • 幂集的空集合代表: 原集合里面一个元素也不选
  2. 空类型只有一个值,空值。空值是Python里一个特殊的值,用None表示。None不能理解为0

    • py >>>bool(None) False >>>None == 0 False

运算符的优先级和结合性

优先级(1最高,8最低) 运算符 描述 结合性
1 x**y 从右向左
2 +x,-x 正,负
3 x*y, x/y, x%y 乘,除,取模 从左向右
4 x+y, x-y 加,减 从左向右
5 x<y, x<=y, x==y, x!=y, x>=y, x>y 比较 从左向右
6 not x 逻辑否 从左向右
7 x and y 逻辑与 从左向右
8 x or y 逻辑或 从左向右

列表

  • 列表可以由零个或多个元素组成,元素之间用逗号分开,整个列表被方括号所包裹
    • >>>empty_list = [ ] #空列列表
    • >>>weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
    • >>>weekdays[2] #下标从0开始 'Wednesday'

列表运算实例

1
2
3
4
5
6
7
8
9
>>>weekdays[4] = 5
>>>weekdays
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 5]
>>> [1,2,3]<[1,2,4] #比较列表大小
True
>>> [1,2,3]+[c,java,python] #加法
[1, 2, 3, 'c', 'java', 'python']
>>> [1]*10 #可以用作列表初始化
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

4. 内置转换函数

函数名 含义
bool 根据传入的参数的逻辑值创建一个新的布尔值
int 根据传入的参数创建一个新的整数
float 根据传入的参数创建一个新的浮点数
complex 根据传入参数创建一个新的复数
str 创建一个字符串
ord 返回Unicode字符对应的整数
chr 返回整数所对应的Unicode字符
bin 将整数转换成2进制字符串
oct 将整数转化成8进制数字符串
hex 将整数转换成16进制字符串
list 根据传入的参数创建一个新的列表

内置转换函数实例

1
2
3
4
5
6
7
8
>>>bool('str')
   True
>>>int(3.6)
   3
>>>float(3)
   3.0
>>>complex(1,2) #传入数值创建复数
   (1+2j)

int函数用法

>>>int() #不传入参数时,得到结果0。
0
>>>int(02)   #去掉0
2
>>>int(        35    )   # 去掉空格
35
>>>int(         3  5   )   #无法转换
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
int("  3  5  ")
ValueError: invalid literal for int() with base 10: '  3  5  '
>>>int(35,8)   #八进制
29 

ord与chr

>>>ord(a) #ASCII码值
97
>>> ord() #汉字‘中’的Unicode码
20013
>>> chr(97) #参数类型为整数
'a'
#8与”8”如何转换?
>>>int("8")
8
>>>chr(8)
"8"

bin, oct和hex

1
2
3
4
5
6
>>>bin(3) #0b为默认
'0b11‘
>>>oct(10)
'0o12‘
>>> hex(15)
'0xf'

str函数和list函数

1
2
3
4
>>> str(123)
'123'
>>> list('abcd') #传入字符串,创建列表
['a', 'b', 'c', 'd']

表达式

  1. 表达式是可以计算的代码片段,由常量、变量和运算符或函数按规则构成,返回运算结果
    1
    2
    3
    4
    5
    6
    7
    8
    >>>7       #表达式
    7
    # 计算表达式 cos(a(x+1)+b)/2,a等于2,x等于5,b等于3
    >>> import math   
    >>> math.cos(2*(5+1)+3)/2
    -0.37984395642941066
    >>>0 and 1 or not 2<True   # 结果为True
    True
    
  2. 条件表达式实现简单分支逻辑:
    1
    2
    3
    4
    5
    # 计算表达式:当n是奇数时为1,偶数时为0
    >>> n=int(input())
    5
    >>> 1 if n%2==1 else 0  #条件表达式
    1
    

条件表达式表示短路运算

  • a or b 等价于 a if a为真 else b
  • a and b 等价于 b if a为真 else a

5. 语句

Python语言常用的有赋值、if语句和for语句。语句通常是一行一条语句。如一行中有多条语句,则用分号(;)分开,如语句太长要跨行时,可以用续行符(\)跨行表示一个语句。

赋值语句

赋值语句用于将名称绑定到特定对象(值),基本形式是变量=值的形式。

【例 2-1】 基本赋值语句

1
2
3
4
x=1
y=2
k=x+y
print(k)
程序输出:
3

多变量赋值

1
2
3
>>>x,y=4,8
>>>print(x,y)
4 8

【例 2-2】 交换a,b值

1
2
3
4
5
a=int(input())
b=int(input())
print(a,b)
a,b=b,a   #a和b交换
print(a,b)

链式赋值

1
2
3
4
5
6
7
8
>>>a=b=c=5
>>>print(a,b,c)
5 5 5
>>>b=b+6
>>>print(a,b,c)
5 11 5
>>>a=(b=5) # 错误!b=5是语句,无返回值
SyntaxError: invalid syntax

赋值和运算符组合

赋值可与+-*/等运算符组合,简化代码书写:

1
2
3
4
5
6
7
8
>>>i=2
>>>i*=3
>>>i
6
>>>j=5
>>>j*=3+1   # 等价于j=j*(3+1)
>>>j
20

if语句

基本二分支if-else语句

格式

1
2
3
4
if 逻辑表达式:
    语句块1
else:
    语句块2
实例:判断奇偶数
1
2
3
4
5
x=int(input())
if x%2==0:
    print("偶数")
else:
    print("奇数")

【例】计算水费

为鼓励居民节约用水,自来水公司采取按用水量阶梯式计价的办法,居民应交水费y(元)与月用水量x(吨)相关:当x不超过15吨时,y=4x/3;超过后,y=2.5x−17.5,小数部分保留2位。

1
2
3
4
5
6
x=float(input())
if x<=15:
   y=4*x/3
else:
   y=2.5*x-17.5
print("水费 = {:.2f}".format(y))

条件语句的三种格式

基本的条件语句 有分支的条件语句 连缀的if-elif-else
if 条件:
语句块1
(书写时必须缩进)
if 条件:
语句块1
else:
语句块2
if 条件1:
语句块1
elif 条件2:
语句块2

elif 条件n:
语句块n
else:
语句块 n+1
(if/elif/else需同一列对齐)
基本的条件语句

格式

if 条件
    语句块1    #分支语句块1,书写时必须缩进。
执行逻辑:条件为True时执行语句块1,为False则跳过,继续执行后续代码。 实例
1
2
3
4
5
6
x = int(input())
y=z=0
if x>20:
    y = 100 # 书写缩进,当x>20时执行
    z = 200 # 书写缩进,当x>20时执行
print(y+z)  # if语句后续的语句

二分支的条件语句

执行逻辑:条件成立执行语句块1,不成立执行语句块2。 实例:比较两个数的大小

1
2
3
4
5
6
7
x,y = input().split()
x,y=int(x),int(y)
if x > y:
    max = x
else:
    max = y
print(max)

嵌套的条件语句
  1. 分支语句(块)中包含另一个if语句,称为条件语句的嵌套,书写时严格遵循缩进规则
  2. else匹配规则:else总是根据它自己所处的缩进和同列的最近的那个if匹配。

实例1

1
2
3
4
5
6
7
if code == 'R':
    if count <20:
        print('一切正常')
    else:
        print('继续等待') #当code为'R'并且count>=20时执行
else:
    print('继续等待')        #当code不为'R'时执行

实例2:求三个数的最大值

x,y,z=input().split()
x,y,z=int(x),int(y),int(z)
if x>y:
    if x>z:
        print(x)
    else:
        print(z)
else:
    if y>z:
        print(y)
    else:
        print(z)

连缀的if-elif-else
  1. 用于实现程序多分支结构,按顺序判断条件,满足某一条件则执行对应语句块,后续条件不再判断。
  2. 适用于分段函数、多条件互斥判断等场景。

【例】分段函数计算 \(f(x) = -1; x<0\) \(f(x) = 0; x=0\) \(f(x) = 2x; x>0\)

1
2
3
4
5
6
7
8
9
x = int(input())
f = 0
if x < 0:
    f = -1
elif x == 0:
    f = 0
else:
    f = 2 * x
print(f)

【练习】温度判断(条件互斥) 1. 输入温度 2. 大于5度且小于30度,输出“舒适”;大于等于30度,输出“热”;小于等于5度,输出“冷”

1
2
3
4
5
6
7
t=float(input())
if t<=5:
    print("冷")
elif t<30:
    print("舒适")
else:
    print("热")

for语句

基本格式

for variable in 列表:
    语句块  # 语句块缩进,表示属于for代码块
执行逻辑:for后面的变量依次被赋值为列表的每个元素,每赋值一次执行一次语句块,直至穷尽列表。

【例 2-5】遍历列表

for i in [1,2,3,4]:
     print(i)
输出:
1
2
3
4
1
2
3
4

range函数

用于生成整数序列,常与for语句配合实现循环,格式range(start,stop,step) - start:计数从start开始,默认是0。例如range(5)等价于range(0,5) - stop:计数到stop结束,不包括 stop。例如:list(range(0,5))[0, 1, 2, 3, 4](无5) - step:步长,默认为1。步长可为负数,实现倒序序列。

range函数实例

1
2
3
4
5
6
7
8
>>> list(range(10))         # 从 0 开始到 10,不包括10
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
>>> list(range(1,11))       # 从 1 开始到11,不包括11
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(range(0, 30, 4))   # 步长为 4
[0, 4, 8, 12, 16, 20, 24, 28]
>>> list(range(0, -10, -1)) # 步长为负数,倒序
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]

sum函数

用于求列表中所有元素的和,常与range函数配合实现连续整数求和。 实例:求1+2+3+...+10的和

1
2
3
4
5
6
# 方法1
print(sum([1,2,3,4,5,6,7,8,9,10]))
# 方法2
print(sum(list(range(1,11))))
# 方法3(最简)
print(sum(range(1,11)))
输出均为:55

【例 2-6】输入n(n>=10),求 1+2+...+n之和

1
2
3
n=int(input())
s=sum(list(range(n+1)))#或s=sum(range(n+1))
print(s)

【例 2-7】输入n(n>=5)求n!(n的阶乘)

1
2
3
4
5
n=int(input())
fac=1
for i in list(range(1,n+1)) :#或for i in range(1,n+1) :
    fac=fac*i
print(fac)

列表和for的结合运用

  1. 列表元素可通过变量计算生成:
    1
    2
    3
    4
    5
    >>>a=3
    >>>b=7
    >>>lst=[a+2,b]
    >>>lst
    [5,7]
    
  2. for循环遍历range生成的序列:
    1
    2
    3
    4
    5
    6
    >>>a=1;b=2;c=3;d=4
    >>>[a,b,c,d]
    [1,2,3,4]
    >>>for i in list(range(1,5)): # list()可不写
            print(i,end=" ")
    1 2 3 4
    

列表推导式

  1. 是从一个或者多个列表快速简洁地创建列表的一种方法,又称列表解析;可将循环和条件判断结合,避免语法冗长,提高程序性能。
  2. 核心优势:代码简洁、执行效率高于普通for循环+列表追加。

基本格式

1
2
3
4
[ expression for item in iterable ]
# expression:输出表达式,对item进行计算/处理
# item:循环变量
# iterable:可迭代对象(列表、range序列等)
实例
1
2
3
>>>nl = [2*i for i in [1,2,3,4,5]]
>>>nl
[2, 4, 6, 8, 10]

带条件的列表解析

在基本格式基础上增加条件判断,仅保留满足条件的元素,格式

[expression for item in iterable if condition]
实例:生成1-7之间的奇数列表
1
2
3
>>>  nl=[i for i in  range(1,8) if i % 2 == 1]       
>>>  nl
[1, 3, 5, 7]

列表推导式的实际应用(级数求和)

【例】求1+1/2+...+1/20之和
1
2
3
print(sum([1/i for i in list(range(1,21))]))
# 或简化为
print(sum([1/i for i in range(1,21)]))
【例】求 1-1/2+1/3-1/4+...前n项和(n>=10)

利用条件表达式实现符号交替:

n=int(input())
print(sum([1/i if i%2==1 else -1/i  for i in range(1,n+1)]))

【例 2-10】求 1-1/3+1/5-1/7+...-1/47+1/49

条件表达式+条件判断结合,先筛选奇数,再实现符号交替:

1
2
3
4
5
# 先生成符号交替的奇数列表
>>>[i if i%4==1 else -i for i in range(1,50) if i%2==1]
[1, -3, 5, -7, 9, -11, ..., 49]
# 求级数和
print(sum([1/i if i%4==1 else -1/i for i in range(1,50) if i%2==1]))

【例】求 6+66+666+...+666...666(n个6)

利用字符串拼接+类型转换生成每一项:

1
2
3
# 生成单个项示例:int('6'*5)=66666
n=int(input())
print(sum([int('6'*i) for i in range(1,n+1)]))

6. 格式化输出

  1. 输出计算结果时,常需要控制显示形式(如保留小数位数、指定宽度、进制转换等)。
  2. format()函数是Python的内置函数,用来设置输出格式,返回值为字符串

基本形式

"需格式化字符串".format(参数表
- 需格式化字符串中包含格式限定符{:xxx},描述参数的显示方式; - 普通字符串原样输出,格式限定符会被format的参数按规则替换。

实例

1
2
3
>>> name="John"
>>> "Hello,{:>6s}".format(name)
'Hello,  John' # >6s表示右对齐,总宽度6,不足补空格

格式限定符详解

格式限定符 输出 说明
"{:d}".format(24) 24 格式化十进制整数,d代表十进制
"{:b}".format(45) 101101 格式化二进制整数,b代表二进制
"{:o}".format(24) 30 格式化八进制整数,o代表八进制
"{:x}".format(24) 18 格式化十六进制整数,x代表十六进制
"{:5d}".format(24) 24 指定宽度5,不足左侧补空格
"{:4d}".format(24879) 24879 参数长度超过指定宽度,按实际长度输出
"{:.2f}".format(1.2449) 1.24 保留2位小数,f代表浮点数(四舍五入)
"{:.2e}".format(53.2453) 5.32e+01 科学计数法,保留2位小数,e代表科学计数法
"{:6.2f}".format(1.2449) 1.24 总宽度6,保留2位小数,不足左侧补空格
"{:9s}".format("hello") hello 格式化字符串,s代表字符串,默认左对齐,总宽度9
"{:>9s}".format("hello") hello 格式化字符串,>表示右对齐,总宽度9

多个参数格式化输出

  1. 格式限定符中可通过数字索引指定format的参数(0表示第一个参数,1表示第二个,依此类推);
  2. 索引可省略,按参数顺序依次匹配。

实例

1
2
3
4
>>>x=3.14159
>>>y=2*x*3
>>>print("{0:.2f} {1:.2f}".format(x,y))
3.14 18.85

字符串的对齐格式化

1
2
3
4
5
6
7
8
9
>>> s="hello"
>>> "{}".format(s)          # 无格式限定,原样输出
'hello'
>>> "{:10s}".format(s)      # 左对齐,总宽度10
'hello     '
>>> "{:^10s}".format(s)     # 居中对齐,总宽度10
'  hello   '
>>> "{:>10s}".format(s)     # 右对齐,总宽度10
'     hello'

【例】华氏-摄氏温度转换表

输入2个正整数lower和upper(lower<upper<100),输出取值范围为[lower,upper)、每次增加2华氏度的转换表,小数部分保留一位。 转换公式\(C=5×(F−32)/9\)(C:摄氏温度,F:华氏温度)

1
2
3
4
5
lower,upper=input().split() # 一行输入两个数,为字符串类型
lower,upper=int(lower),int(upper)        # 字符串转整数 
for i in range(lower,upper,2):
     print(i,"{:5.1f}".format(5*(i-32)/9))
     # 也可指定参数索引:print("fahr={0:d} Celsius={1:5.1f}".format(i, 5*(i-32)/9))
程序输入
30 40
程序输出
1
2
3
4
5
30  -1.1
32   0.0
34   1.1
36   2.2
38   3.3

*7. 位运算

  1. 位运算符用于按二进制位进行逻辑运算,操作数必须是整数
  2. 运算时先将整数转换为二进制补码形式,按位运算后再转换回十进制。

位运算符详解

运算符 说明 示例(a=5=0b0101,b=17=0b10001) 运算结果
& 按位与:两个相应位都为1,结果为1,否则为0(类似二进制乘法) a & b 1(0b00001)
| 按位或:两个相应位有一个为1,结果为1,否则为0(类似二进制加法) a | b 21(0b10101)
^ 按位异或:两个相应位相异(一个1一个0),结果为1,否则为0 a ^ b 20(0b10100)
按位取反:对每个二进制位取反(1变0,0变1),结果为原数取反加-1 ~a -6
<< 左移动:各二进位全部左移若干位,高位丢弃,低位补0 a <<2 20(0b10100)
>> 右移动:各二进位全部右移若干位,正数高位补0,负数高位补1 a >>2 1(0b0001)

【例2-13】a & b运算的二进制表示

1
2
3
4
5
6
a=5
b=17
print("  ","{:>08s}".format(bin(a)[2:]))  # bin(a)[2:]去掉0b前缀,>08s右对齐补0至8位
print("& ","{:>08s}".format(bin(b)[2:]))
print("-----------")
print("  ","{:>08s}".format(bin(a&b)[2:]))
运行程序,显示
1
2
3
4
    00000101
&   00010001
-----------
    00000001

*8. 数据表示

基本概念

  1. 数据:数字、文字、图形图像和声音等所有计算机可处理的信息;
  2. 对象:Python中用对象表示所有数据,一切皆对象;
  3. 对象三要素
  4. id:对象的唯一标识,代表对象在内存中的存储位置
  5. type:对象的类型,决定对象的取值范围和可执行的操作;
  6. value:对象的值,即对象存储的具体数据。

实例:对象数字“1”的三要素为 (id(1), type(1), 1)

对象的可变性

根据对象的值是否可修改,将Python对象分为可变对象不可变对象。 1. 可变对象:对象的值可以修改,修改值后对象的id不变(内存地址不变); 2. 不可变对象:对象的值不可修改,修改值会创建一个新的对象,原对象id不变,新对象有新的id

实例验证

1
2
3
4
5
6
>>> a=5;lst=[3,9,78]
>>> print(id(a),id(lst))  # 打印初始id
1549134400 55838560
>>> a=8;lst[1]=45         # 修改a的值,修改列表lst的元素
>>> print(id(a),id(lst))  # 再次打印id
1549134448 55838560      # a的id改变,lst的id不变

Python常用对象的可变性: - 不可变对象:数字(int/float/complex)、字符串(str)、元组(tuple)等; - 可变对象:列表(list)、字典(dict)、集合(set)等。

作业易错题

Q1

1
2
3
a=int(input())    
n=int(input())    
print(sum([int('a'*i) for i in range(1,n+1)]))

这种写法是不对的,'a'并不能把它转化成字符串,应用str(a)

Q2

python中没有自增自减,故++i会被识别成两个正