580 likes | 729 Views
计算机编程导论 - Python 语言. 第 2 讲 数据. 讲课教师:常姗 2014. 3. 4. 目标. 掌握数据类型的基本概念 熟悉 Python 中基本数值类型 了解计算机中如何表达一个数值 掌握类型检查和类型转换的概念 能够阅读和编写简单处理数值的程序. 数据处理. 计算机 = 数据处理和存储的机器 计算 = 数据 + 处理 问题求解 = 信息表示 + 解法表示. 现实世界问题. 信息. 解法. 机器世界程序. 数据. 处理. 数据. 抽象( abstraction ):抽取与 问题求解有关的信息 进行计算机表示 .
E N D
计算机编程导论 -Python语言 第2讲 数据 讲课教师:常姗 2014. 3. 4
目标 • 掌握数据类型的基本概念 • 熟悉Python中基本数值类型 • 了解计算机中如何表达一个数值 • 掌握类型检查和类型转换的概念 • 能够阅读和编写简单处理数值的程序
数据处理 • 计算机=数据处理和存储的机器 • 计算=数据+处理 • 问题求解=信息表示+解法表示 现实世界问题 信息 解法 机器世界程序 数据 处理
数据 • 抽象(abstraction):抽取与问题求解有关的信息进行计算机表示. • 忽略与问题求解不相关信息 • 抽象是对问题进行简化的重要手段! • 数据(data):现实世界事实或信息在计算机中的符号化表示. • 温度:表示为35,或95,或"摄氏35度" • 学生:
数据类型 • 为了更精细地表示信,编程语言提供不同的数据类型. • 不同类型具有不同的存储方式和处理方式. • 每种类型包含一个合法值的集合,以及一个合法运算的集合. • 为何要区分数据类型? • 类型信息可为系统利用 • 编译器/解释器利用类型检查,可以发现程序错误. • 数据类型检查是程序员的责任 • Python提供的基本数据类型-内建(built-in)类型 • 数值(int,long,float)、字符串(str)、布尔值(bool)、列表(list)、元组(tuple)、字典(dict)等。 Lu Chaojun, SJTU
计算机如何存储数据? • 二进制 • 原因:电子开关的两个状态,ON / OFF • 每一个开关能够表示一个二进制数(1/0),称为位(bit) • 把更多开关组合在一起,可以表示更多的信息,例如三位数据。 • 8位称为一个字节(Byte) • 如果一共有n位,可以表示多少种数值? • 存储器大小 • 210 —K, 220 — M, 230 —G, 240 —T
整数类型 • 整数类型int • 不带小数点 • 例如: 123 -456 0 • 计算机可存储整数的精确值 商的小数部分直接舍弃!
整数的限制 • 计算机中的数值是现实数值的一种计算机表示,两者不同! • 例如:整数集I是无穷集,但int是有穷的. • 二进制是计算机表示数据的基础 • n位二进制只能表示2n个不同值 • 整数若用32位表示,则int范围为231 ~ 2311 >>> 2147483647 2147483647 >>> 2147483648 2147483648L • 你用的计算机用多少位来表示整数? • int 类型的大小跟机器有关
长整数类型 • 在python中,long类型与机器无关,它可以根据数值的需要使用任意大小的存储器空间 • 数值加后缀”L”或”l”,如5L, 1234567890000L • 5L和5具有完全不同的计算机表示! • 例如: >>> type(5) <type ‘int’> >>> type(5L) <type ‘long’> • Python自动把超出int类型的数值转换成长整型 • 为何还需要 int? • 经验:long的运算效率远低于int, 因此能用int就不用long.
自动类型转换 • 理论上,相同类型的数据才能相互运算. 例如:>>> 2 + 3 >>> 4L – 5L • 类型相近的数据也可以相互运算,系统会执行自动的类型转换. 例如:>>> 2 + 3L 5L • 系统先将int类型的2转换成long类型的2,从而可与3L运算.注意不是long转换成int!
计算是次序的艺术 • int类型的范围: 231 ~ 2311 >>> 2**31 - 1 2147483647L • 未超出int范围,为什么结果是long? • 2**31已经超出了int的范围 • 如何计算2311,并使结果在int中? >>> 2**30 – 1 + 2**30 2147483647 • 计算思维与数学思维是不同的!
浮点数类型 • 浮点数类型float • 带小数点,允许小数点后面没有数字 • 例如: 3.14 -2.718 13. 0.0 • 计算机只能存储浮点数的近似值! 保留小数部分!
浮点数类型的限制 • 有限的float不等于数学中的实数集R • 浮点数在计算机内部是用有限的固定长度的二进制数来表示的,无法精确表示. >>> 1.2 – 1.0 0.19999999999999996 >>> 2.2 – 1.2 1.0000000000000002 >>> 2.0 – 1.0 1.0 • 运算效率比整数类型低 • 科学记数法:Python自动用来表示很大或很小的浮点数.
类型转换 • 在混合类型表达式中,Python自动转换: int long float • 例如:>>>type(2+3l+4.5) <type ‘float’> • 手动类型转换:利用int(), long(), float() • 思考:求整数的平均值时用哪个更精确? avg = sum / count avg = float(sum) / count avg = float(sum / count) • 更简单的方法? >>>round(3.5) 4.0 • 浮点数取整时直接丢弃小数部分,如何做到四舍五入? • int(x+0.5) • 调用内建函数round( ),将浮点数四舍五入,收入后仍为float类型
数学库 • 库:包含有用定义的模块 • 最常见的是函数定义 • 一般由系统提供,也可自己开发给别人用. • 数学库:包含有用的数学函数 • 数学库的两种导入方式: import math from math import * (*的意思是“所有定义”) 导入模块的作用相当于将该模块中的代码复制到自己程序中 • 数学库函数的调用:例如求平方根 math.sqrt(4)(math已导入) sqrt(4)
数学库中的常用函数 pi:常数 e:常数e sqrt(x):平方根 sin(x), cos(x), tan(x):三角函数 asin(x), acos(x), atan(x):反三角函数 log(x), log10(x):自然对数与常用对数 exp(x):e的x次方 ceil(x):x的最小整数 floor(x):x的最大整数
常量与变量 • 常量:不能改变的数据,从表面形式就知道是什么数据 • 例如: "Hello,World!", 3.14, ... • 变量:可以改变的数据,用标识符来命名 • 变量只是“占位符”,必须用具体数据赋值后才有意义! • 变量若未赋值,称其为“未定义”,程序报错! • 变量的类型:变量存储数据的类型。
变量 • 是一个可以存放某种数据的内存空间,可以有名字 • 名字:标识符(identifier) • 必须以字母或者下划线开头,后跟字母(区分大小写)、数字和下划线的任意组合,例如,class1, _temp, _Temp • 程序员可以任意选取符合规则的名字,但被python保留的关键字(keywords)不能被用于当作名字: • 编程习惯: • 选择有意义的名字 • 例如,用’_’来连接多个词,my_class, speed_of_car
变量 • 在python中通过赋值语句来定义一个变量并为其赋值 • 赋值:<变量> = <表达式> • 例如: >>> message = 'And now for something completely different' >>> n = 17 >>> pi = 3.1415926535897932 • Python中的并行赋值: • 例如: >>> x,y = "hello",3.14 >>>x,y=y,x
操作符、操作数和表达式 • 操作符(operators):表示某种运算的特殊符号 • 例如,+,-,*,/,>> • 操作数(operands):操作符运算的对象 • 常量、变量 • 例如,20+27,8**2,2/3, x/3 • 表达式(expressions):操作符与操作数的组合 • 例如, • 编程习惯:表达式中可以插入空格,便于理解
布尔类型 • 布尔类型bool • 合法值:True, False.用于表达"真","假"数据 >>> 3 > 2 True >>> 4 + 5 == 5 + 4 True >>> a = -8 >>> a * 2 > a False >>> "like" < "lake" False >>> 2 = 2 syntaxError: can’t assign to literal 初学者易错!
布尔表达式与逻辑运算 • 布尔表达式 • <表达式1> <关系运算符> <表达式2> • 关系运算符:<, >, <=, >=, ==, !=(<>) • 例如,x > 5, y != 32 • 逻辑运算 • <布尔表达式1><逻辑运算符><布尔表达式2> • 逻辑运算符:and, or, not • 例如,x > 0 and x < 5 n%2 == 0 or n%3 == 0 not (x>y)
布尔代数 • and类似乘法,or类似加法,True和False类似1和0 • 逻辑运算优先次序:not>and>or • a or not b and c <=> a or ((not b) and c) • 任何内建类型的值都可以解释为布尔值 • 数值int,long,float:0为False,非0为True • 字符串:空串为False,非空字符串为True 真值表
非布尔表达式的逻辑运算 • <非布尔表达式1><逻辑运算符><非布尔表达式2> • a,b是任何表达式 • a and b,若a的值解释为False,则返回a的值,否则返回b的值。 • a or b,若a的值解释为False,则返回b的值,否则返回a的值。 • not a ,若a的值解释为False,则返回True,否则返回False。 例如: >>>2 and “hello” ‘hello’ >>>( 4 > 5 ) or 3 3
文本数据 • 计算机应用 • 科学计算 • 信息管理 • 信息管理中大量的数据都是文本数据. • 如:姓名,地址,简历,身份证号码,电话号码等 • 计算机中用字符串来表示文本数据. • 字符串:由字符组成的序列 • 字符:计算机中表示信息的最小符号 • 可打印字符 • 字母(大小写),阿拉伯数字,标点符号…… • 控制字符 • 回车,换行,退格…… Lu Chaojun, SJTU
字符串类型 • 问题1:如何区分字符串数据和程序构件? • 字符串字面值:用一对引号(单/双/三)括住. >>>'hello world' >>>"~!@#$%^&*" >>>"汉字也是字符" >>>'''line one, line two''' >>>"""line one, line two""“ • 字符串类型str:字符序列 界定符 三引号可使字符串跨行
字符的转义 • 字符串本身含有引号怎么办? • 含有单引号:串用双引号括住 "I'm a student." • 含有双引号:串用单引号括住 'He said, "OK."' • 两者都有时用什么引号? He said, " I'm a student." • 一般的做法:用转义字符\来转变字符含义 "He said, \"I'm a student.\"" 'He said, "I\'m a student."' \”:使双引号不再作为界定符
字符串操作:取字符 负号代表“倒数” • 字符串是字符序列,可通过位置索引访问每个字符. • 每个字符在序列里的位置由一个从0开始的整数编号指定。 • 支持从后往前的索引—-1代表倒数第一个位置。 • 一般形式:<字符串>[<索引>] • 对长度为n的字符串,索引可以 • 是大于0的数:自左向右为0 ~ n1, 或者 • 是负数:自右向左为1, 2, 3,…, n • 例如:若str = "Hello Bob",则 str[0]或str[9]是'H' str[5]或str[4]是' ' str[8]或str[1]是'b' str[9]或str[10]越界出错
字符串操作:取子串 • 切分:取一个索引范围内的字符. 一般形式:<字符串>[<start>:<end>] • 所取子串:位置索引从start ~ end1 • 注意:不包含end位置! • start和end可省略,默认值为0和n(长度为n的字符串) • 冒号不可省略 • 例如:若str = “Hello Bob”,则 str[0:3]是'Hel' str[5:9]是' Bob' str[:5]即str[0:5] str[5:]即str[5,9] str[:]即str[0:9] str[2:-2]即’llo B’ 负号代表“倒数”
字符串操作 • 字符串不能进行数学操作 • 即使看起来像数字也不行! • 例如,以下操作均非法 >>> ‘2’ – ‘1’ >>> ‘eggs’ / ‘easy’ >>> ‘third’ * ‘a charm’ • 字符串可以使用操作符‘+’及‘*’ • 但功能和你想的不一样!
字符串操作:连接/复制 • 两字符串的连接 <string1> + <string2> • 例如:"Hello" + "Bob"得到"HelloBob" • 一个字符串的复制 • 例如:3*"Hi"和"Hi"*3都得到"HiHiHi" • 子串检测 • 例如:"ok" in "cook"返回True • 串长度函数len() • 例如:len(2*"Good" +3*"Bye")返回17
字符串操作 • 字符串类型的值不能修改 • 例如:试图将"Tom"修改为"Tim" >>> name = “Tom” >>> name[1] = “I” • 字符串操作整理
字符的机内表示 • 与数值一样,计算机内用二进制数表示每一个字符. • 因此字符本质上仍然是数值. • 表示字符的这个数值称为字符的编码. • 要保证不同字符的编码不同。 • 问题:计算机采用什么字符集?其中每个字符用什么编码? • 对这个问题的不同回答就导致了许多不同的字符编码系统.
编码标准 • 不同计算机若用不同编码,则彼此无法沟通. • 标准化 • ASCII:单字节编码,但只用到7位(0~127) • 96个可打印字符,32个控制字符 • ISO/IEC 8859-1(Latin-1):单字节用满8位(0~255) • GB2312:两字节(7445字符/6763汉字) • GBK:两字节(21886字符/21003汉字),中文缺省编码 • GB18030:最多四字节(76556字符/70244汉字) • ISO/IEC 10646或Unicode:最多四字节.
字符与编码 • Python 2.7默认编码为ASCII. • 求给定字符的编码: ord() ord('a')可得97 • 求给定编码的字符:chr() chr(97)可得'a‘ • ‘a’=‘A’+32 • ‘b’=‘B’+32 • ‘c’=‘C’+32 • …… • A,B,C,D…… 依次加1 • 控制字符
字符与编码-续 • 控制字符 • 字符的比较 • 其实是字符编码的比较 • Q:非ASCII字符怎么办? • A:用Unicode字符串 • >>>print u'A\xc4B' • AÄB 注意:加前缀u代表Unicode字符串
Python程序中使用汉字 • 国际化:希望程序中显示中文信息 • 中文Windows的缺省编码是GBK >>>'汉' \xba\xba 输入'汉'即输入其GBK编码 >>>print '\xba\xba' 或用'汉' 汉 print语句能正确解码GBK >>>print '\xba\xba\xc4' 不能解码! • “混合双打”? • 最好用Unicode >>>print u'\u6c49\xc4' 汉Ä GBK Latin-1
数值与字符串的互相转换 • eval()函数:将字符串当作数值表达式进行计算. • 语法: eval(<string>) • 例如: eval("3+4*5") • str()函数:将数值当作字符串 • 语法: str(<expr>) • 例如: str(3+4*5)
字符串库 • 模块string:包含了很多有用的字符串处理函数 • 例如 capwords(s);count(s,sub);find(s,sub); rfind(s,sub);replace(s,oldsub,newsub) >>> from string import * >>> capwords("hello world!") 'Hello World!' >>> count("知之为知之不知为不知","不知") 2 >>> find("知之为知之不知为不知","不知") 10 >>> rfind("知之为知之不知为不知","不知") 16 >>> print replace("知之为知之不知为不知","知","zhi") zhi之为zhi之不zhi为不zhi (思考用import string语句导入的情况,上机练习!)
列表类型(1) • int,long,float,bool都是"原子"值 • str是由多个字符组成的序列 • 列表类型list • 是集合体--多个数据组成的“序列(sequence)” • 有序存储一组数据(元素)的数据结构 • 基本形式: [<表达式1>, <表达式2>,…, <表达式n>] • 例如 [] 空列表 [1,2,3] ["list","sequence"]
列表类型(2) • list与其他语言中的数组相似,但不同 • 不固定长度,可以增删成员 • 不要求各成员都是相同类型的 • 成员本身也可以是列表 • 例如 [2,"apples"] [1,"two",3.0,True] [[1,"apple"],[2,"pears"]] • 表示矩阵 >>> m = [[1,2,3],[4,5,6]] >>> print m [[1,2,3],[4,5,6]]
列表操作(1) • 通过索引访问 • 通过在序列中的位置编号来访问成员,非常类似于字符串索引 <列表>[<位置编号>] • 例如 >>> x = [1,"two",3.0,True] >>> x[0] 1 >>> x[-1] True >>> x[1+1] 3.0 >>> x[4] • 思考:会发生 • 什么情况?
列表操作(2) • 访问子列表 • 指定序列中的开始和结束位置 <列表>[<开始位置>:<结束位置>] • 例如 >>> x = [1,"two",3.0,True] >>> x[0:2] [1,'two'] >>> x[1:] ['two',3.0,True] >>> x[:-1] [1,'two',3.0] A:为什么列表的索引机制和字符串很像? Q:字符串是列表的特例—由字符组成的列表!
列表操作(3) • 索引和子列表操作都和字符串相似 • 列表也有+和*操作,意义和字符串类似 >>> [1,3,5]+[2,4] [1,3,5,2,4] >>> 4*[0] [0,0,0,0] • 列表vs字符串:字符串不能增删改,而列表可以 >>> x = [1,3,5,7,9] >>> x[0] = 2 >>> x [2,3,5,7,9] >>> x = x + ['two'] >>> x [2,3,5,7,9,'two'] 组合类型 简单类型 • 试图将"Tom"修改为"Tim" • >>> name = “Tom” • >>> name[1] = “I”
与列表有关的几个内建函数 • 删除列表成员 del() • >>> x = [1,2,3] • >>> del x[1] • >>> x • [1,3] • 求列表长度 len() >>> len([1,3,5]) 3 >>> x = 4*[0] >>> len(x) 4 • 产生整数列表 range() • 一般形式 range(<起点>,<终点>,<步长>) • 起点和终点可省略,默认值0,1;不包括终点 >>> range(10) [0,1,2,3,4,5,6,7,8,9] >>> range(1,10,2) [1,3,5,7,9] >>> range (10,-1,-3) [10,7,4,1]
元组类型 • 元组类型tuple • 用圆括号括起的成员集合体 • 同样是有序的一组用逗号分隔的数据 • 和列表基本相同,只是不能增删改成员 • len()和indexing操作 >>> t1 = (1,2,3) >>> t2 = () >>> print (8),(8,) >>> t1[1] >>> t1[0:2] >>> t1 + t2 解释为单个数值8,逗号不可省略
输入(1) • 程序中数据如何提供? • 编程时提供 >>> x = 3.14 • 运行时输入: <变量> = input(<提示字符串>) • 在屏幕上输出提示符字符串 • 等待用户输入,以回车键表示输入完毕 • 将用户输入作为表达式求解 • 将结果赋予变量 >>> x = input("请输入:") >>> n,a = input("请输入姓名和年龄") • 程序例: eg2_1.py vs eg2_2.py
输入(2) eg2_2.py name = input("Please input name:") age = input("Please input age:") birthYear = 2012 - age print name,"was born in",str(birthYear)+"." • eg2_1.py • name = “Lucy” • age = 21 • birthYear = 2012 - age • print name,"was born in",str(birthYear)+"." 执行结果: >>> import eg2_1 Lucy was born in 2005. 注意:引号 执行结果: >>> import eg2_2 >>> Please input name: “Lucy” >>> Please input age: 21 Lucy was born in 2005.
输入(3) • 另一种输入函数 <变量> = raw_input(<提示字符串>) • input将输入内容作为表达式来求值,而raw_input将输入整体视为字符串. • 例如 >>> n = raw_input("输入姓名") 输入姓名 Lucy >>> a = raw_input("输入年龄") >>> 2013 – eval(a)