java程序员的python之路(数据类型)
2017-06-15 18:57
435 查看
环境
64位windows10+eclipse + python插件 + python3.5具体安装步骤,可自行度娘。
数据类型
Python3 中有六个标准的数据类型,数字,字符串,列表,元组,集合,字典。这和java里的分类方法有些不同,java分8种基本类型和集合。python之所以把java的集合列位标准数据类型,在于python中一切皆对象的思想。而在java中8种基本类型并不是对象。数字
python的数字类型包括int(整数),float(浮点数),bool(布尔)和complex(复数)。我们可以像下面这样声明数字变量并且赋值:vint = int(1) vfloat = float(1) vbool = bool(1) vcomplex = complex(1) print(vint) print(vfloat) print(vbool) print(vcomplex)
输出结果如下:
1 1.0 True (1+0j)
python中我们并不需要注明变量的类型(静态类型),这和java截然不同,看到一个变量的时候不知道它的类型,这让我这个初学者很是头疼,对于代码阅读和后期维护会产生一定的影响。
int(),float(),bool(),complex()相当于构造函数(可以用来做类型转换使用),使用相应构造函数可以构造一个我们需要的变量,当然一般我们不会调用标准数据类型的构造函数来构造一个变量,有更简单的方法,就和java里一样,像下面这样,结果是一模一样的:
vint = 1 vfloat = 1.0 vbool = True vcomplex = 1 + 0j
先说一下整型,在java中有4种整型byte,short,int,long,分别占用1,2,4,8个字节的空间。而python只有int一种整数类型,我们可以使用type函数来查看变量的类型。使用sys.getsizeof()函数来获得对象占用的内存空间,单位是字节。使用sys需要导入sys模块,代码如下:
import sys vint = 0 print(type(vint)) print(sys.getsizeof(vint))
输出结果如下:
<class 'int'> 24
第一行的输出,说明这是一个int类型,没什么毛病。第二行的输出是占用的内存空间,竟然是24个字节,我的老天奶奶,作为一个java程序员,一个整形的变量怎么能占到24个字节,就算java里最大的long也才占用8个字节,这差距太大了,肯定有猫腻。经过一番查证,这个内存空间还包括一些其他的信息,必须垃圾收集信息和其他不知道的一些信息,这些信息占用16个字节,剩下的8个字节才是真的int占用的空间,这就说的过去了。
而且python中的int并不会出现越界的问题,也就是说可以可以存一个任意大的整数,只要内存足够的话,随着数值的增大,占用的空间也随之增加。我们来试一个大数:
vint = 99999999999999999999999999999999999999999999999999999999999999999999999999999999 print(sys.getsizeof(vint))
这个输出的结果将会是60个字节。这就比较happy了,java中遇到大数的时候,我们就不得不使用BigDecimal。python一个int全搞定。
再说一下浮点数,Java中浮点类型分为单精度和双精度即float和double,分别占用4,8字节,浮点数在计算的时候会损失精度。而python中只存在float一种类型,占用空间24个字节(除了额外信息就是8字节),因为浮点数在内存中存储结构的独特(至于是什么结构可以自行度娘),并不会想int那样数越大占用的空间越大,永远额定24个字节。看下面的代码:
import sys vfloat = 99999999999999999999.123456789123456789123456789123456789123456789 print(vfloat) print(type(vfloat)) print(sys.getsizeof(vfloat))
输出结果如下:
1e+20 <class 'float'> 24
第二、三行不用多说,我们发现第一行的值出现了精度问题。这和java中一样浮点数都存在精度问题。解决精度问题和java如出一辙,需要导入decimal了,如下:
import decimal as dc vfloat = dc.Decimal("99999999999999999999.123456789123456789123456789123456789123456789") print(vfloat)
输出结果将会是:99999999999999999999.123456789123456789123456789123456789123456789,精度一点都没有损失。
在聊一下bool类型,只包含两个值true和false。java虚拟机规范中貌似是说boolean类型编译后其实是int类型,1表示true,0表示false,boolean数组编译后是byte数组,所以说它占用空间你说是1字节也对,说4字节也没问题,我们就不深究了。我们看一下python中的bool是什么情况,如下代码:
import sys vbool1 = False vbool2 = True print(type(vbool1)) print(sys.getsizeof(vbool1)) print(sys.getsizeof(vbool2))
输出结果如下:
<class 'bool'> 24 28
诶呦我去,怎么内存空间一个24字节一个28字节,其实你把整形0和1的空间输出一下就明白了,也是24和28。说明python中的bool类型也是用int来处理的,不同的是python中0表示false,其他任何数都表示true,验证如下:
vbool1 = bool(0) vbool2 = bool(100) vbool3 = bool(-100) print(vbool1) print(vbool2) print(vbool3)
输出如下:
False True True
复数,在我java的编程经历中从来没有遇到过。python中支持复数还是惊到了我,看来python对数学的支持力度还是很大的。这里就先不研究复数了,有兴趣的自行研究。
谈到数字,我们不得不谈一下运算符,索性在这里我们研究一下所有的运算符,java中运算符可总结如下几类:
种类 | 运算符 |
---|---|
赋值运算符 | = , += , -= , *= , /= , %= |
算数运算符 | +,- , * , / , ++ , – , % |
关系运算符 | ==,!=,>,<,>=,<=,instanceof |
逻辑运算符 | && , | | |
位运算符 | & , | , ! , ^ , ~ , << , >> , >>> |
num1 = 2 num2 = 2 #a+=b 相当于 a = a + b num2 += num1;print(num2) #a-=b 相当于 a = a - b num2 -= num1;print(num2) #a*=b 相当于 a = a * b num2 *= num1;print(num2) #a/=b 相当于 a = a / b num2 /= num1;print(num2) #a%=b 相当于 a = a % b num2 %= num1;print(num2)
输出结果如下:
4 2 4 2.0 0.0
从输出的第三行,我们可以看到,两个int类型的数相除以后变成了一个float类型的数,而在java中会直接取整。
下面看算数运算符,遗憾的是python并不支持自增和自减运算符,这么简单的好用的语法糖,其实可以支持一下的。庆幸的是python中支持幂运算符号,也就间接支持了开方运算(不得不说python对数学的支持力度)。因为python中int相除会按照float类型运算,所以又多出了一个运算符那就是整除运算符,具体代码如下:
num1 = 3 num2 = 2 #加法 num = num1 + num2;print(num) #减法 num = num1 - num2;print(num) #乘法 num = num1 * num2;print(num) #除法,结果会是一个浮点数 num = num1 / num2;print(num) #取余数 num = num1 % num2;print(num) #幂 num = num1 ** num2;print(num) #开方 num = num2 ** 0.5;print(num) #整除 num = num1 // num2;print(num)
输出结果如下:
5 1 6 1.5 1 9 1.4142135623730951 1
关系运算符的运算结果是一个bool类型,一般多用在if语句中,目前我还不知道python的if语句的写法,所以这里之研究结果,代码如下:
num1 = 3 num2 = 2 #大于 print(num1 > num2) #小于 print(num1 < num2) #等于 print(num1 == num2) #大于等于 print(num1 >= num2) #小于等于 print(num1 <= num2) #不等于 print(num1 != num2) #是否某类型的对象 print(isinstance(num1,int))
输出结果如下:
True False False True False True True
可见python对于这些关系运算符都是支持的。
逻辑运算符在python中的写法和java中有很大的区别,代码如下:
num1 = True num2 = False #逻辑与 print(num1 and num2) #逻辑或 print(num1 or num2) #逻辑非 print(not num2)
输出结果如下:
False True True
看一下位运算符,此运算符是按照二进制来运算的,不了解二进制表示方法的可以现行度娘一下,代码如下所示:
num1 = 0b1111 num2 = 0b0000 #与,全1为1,有0为0 print(num1 & num2) #或 ,有1为1,全0为0 print(num1 | num2) #异或,相同为0,不同为1 print(num1 ^ num2) #取反 1为0 0为1 print(~num1) #左移 移几位相当于乘以2的几次方 print(num1 << 1) #右移 移几位相当于除以2的几次方 print(num1 >> 1)
输出结果如下:
15 0 15 15 -16 30 7
python中还有两种运算符,叫做成员运算符(in,not in)和身份运算符(is,is not),成员运算符用在字符串,列表和元组中,身份运算符用于比较两个对象的存储单元是否相同,看下面的代码:
str1 = "abdcdef" str2 = "abdcdef" str3 = "abdcdefg" #判断a字符串是否在str中 print("a" in str1) #判断z字符串是否不在str中 print("z" not in str1) #判断str1和str2是否引用自一个对象 print(str1 is str2) #判断str1和str3是否引用不同对象 print(str1 is not str3)
输出结果如下:
True True True True
综上所述,python的运算符总结如下表:
种类 | 运算符 |
---|---|
赋值运算符 | = , += , -= , *= , /= , %= |
算数运算符 | +,- , * , / , % , ** , // |
关系运算符 | ==,!=,>,<,>=,<=,isinstance |
逻辑运算符 | and , or , not |
位运算符 | & , | , ^ , ~ , << , >> |
成员运算符 | in , not in |
身份运算符 | is , is not |
序列
在说字符串之前,我们需要先了解一下python中的序列,序列就是一系列的元素排列在一起。 Python包含 6 中内建的序列,包括列表、元组、字符串、Unicode字符串、buffer对象和xrange对象。常用的就是字符串,列表和元组。所有的序列类型都可以进行特定的操作:索引(indexing)、分片(sliceing)、加(adding)、乘(multiplying)以及检查某个元素是否属于序列的成员(成员资格)。下面我们用列表演示一下序列的基本操作,如下代码:list = [1,2,3,4,5,6,7,8,9,0] #索引:第一个索引是 0,第二个则是 1,依次类推。序列中的最后一个元素标记为 -1,倒数第二个元素为 -2,依次类推 print(list[1]) #分片: print(list[0:5]) #按步长分片 print(list[0:9:2]) #序列加法 print(list + list) #序列乘法 print(list * 2) #成员资格 print(10 in list) #序列长度 print(len(list)) #序列最大值 print(max(list)) #序列最小值 print(min(list))
输出结果如下:
2 [1, 2, 3, 4, 5] [1, 3, 5, 7, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0] [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0] False 10 9 0
字符串
字符串是最常用的类型。我们先来简单的回顾一下java中的字符串,使用双引号括起来是它的表现形式(使用单引号表示的是单个字符),而且字符串是不可变的,也就是说每个字符串在内存中是独一份,创建之后不能修改,可以进行子串查找,拼接,替换,分割等操作。用脚趾头想想python中的字符串也得具有这些功能,只是方式和方法可能不同。python中的字符串是一种序列,可以使用双引号,也可是使用单引号。说明python中不存在单个字符的说法,也就没有字符(char)这种数据类型。同样的python和java的字符串都是不可变的,尝试修改就会抛出异常。但是python的字符串有着比java更丰富,更灵活的操作,下面我们通过程序来说明:
#通过单引号 和 双引号 来创建字符串对象 str1 = 'hello world' str2 = "hello world" #根据访问字符串中的单个元素(索引) print(str2[0]) #查找子串出现的第一个位置 print(str2.find("o")) #查找子串出现的最后个位置 print(str2.rfind("o")) #从下标2(包含)到下标4(不包含)(分片) print(str2[2:4]) #从下标7到结尾 print(str2[7:]) #分割字符串成多个子串 print(str2.split(" ")) #使用+连接字符串(加法) print(str1 + str2) #使用*复制字符串 print(str1 * 2)(乘法) #结果为True,说明之创建了一个 hello world 对象,str2只是指向了那段内存地址而已 print(str1 is str2) #是否包含字符串 print("h" in str2) #是否不包含字符串 print("h" not in str2)
输出结果如下:
h 4 7 ll orld ['hello', 'world'] hello worldhello world hello worldhello world True True False
可见字符串除了拥有序列的基本操作,还提供了更丰富的操作,不如,find和split方法等。
转义字符
谈到字符串我们难免就会遇到转义字符,比如我们要字符串包含一个双引号,在python中转义方式和java是一样的使用反斜杠进行转义,如下代码:str1 = "I say:\"you are beatiful.\""; print(str1)
输出结果如下:
I say:"you are beatiful."
这里我们列举几个常用的转义字符:
转义字符 | 解释 |
---|---|
\n | 换行 |
\r | 回车 |
\’ | 单引号 |
\” | 双引号 |
\ | 反斜杠符号 |
格式化
python字符串支持输出格式化,java中在1.5之后也加入了这一项功能。不同语言支持格式化的方式都是相同的,但最基本的用法是将一个值插入到一个有字符串格式符 %s 的字符串中。看一段代码就了解了:print ("我叫 %s,今年 %d岁!" % ("小明", 10))
输出结果如下:
我叫 小明,今年 10岁!
下面列举一下,python常用的格式化符号,就不再一一写代码了,可以自己写代码验证:
格式化符号 | 解释 |
---|---|
%s | 字符串 |
%d | 整数 |
%f | 浮点数 |
%e | 科学计数法显示浮点数 |
三引号
python三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。代码如下:para_str = """hello \n world " jjjjjjjj hhhhhh \\ """ print (para_str)
输出结果如下:
hello world " jjjjjjjj hhhhhh \
三引号使得程序员只关注字符串本身,而不用考虑特殊字符需要转义的问题。
内建函数
字符串还提供了很多内建函数供我们使用,下面列举几个常用的内建函数,注释是函数的说明,代码如下:str = "hello world" #首字母大写 print(str.capitalize()) #子串出现的次数 print(str.count("o")) #是否某字符串结尾 print(str.endswith("ld")) #是否都是数字 print(str.isnumeric()) #是否都是空格 print(str.isspace()) #转大写 print(str.upper()) #转小写 print(str.lower()) #字符串出现位置 print(str.find("o")) #分割字符串 print(str.split(" "))
输出结果如下:
Hello world 2 True False False HELLO WORLD hello world 4 ['hello', 'world']
对于字符串,我们就先学这么多。
列表
列表也是python中最常用的数据类型,因为列表是一种序列,所以它支持序列的所有操作,比如索引,分片,加,乘,检查成员。要创建一个列表,只需要用逗号分割各个数据然后用中括号括起来。数据不分类型,也就是说你可以把不同类型的数据放到一个列表中。python的列表的外观很像java中的数组,单是能放不同类型的数据有很像java中的List(不考虑泛型)。所以我们全切把python的列表看做是java中数组和List的综合体。下面看一下列表的基本操作。#创建列表 list1 = [1,"hello",10.1,True,"hello"] list2 = [10,True,False,11.1,"world"] #索引 print(list1[1]) print(list1[-1]) #分片 print(list1[2:]) print(list1[:2]) #加法 print(list1 + list2) #乘法 print(list2 * 2) #检查成员 print("hello" in list1) #根据索引改变元素 list1[0] = 100 print(list1[0]) #根据索引删除元素 del list1[0] print(list1) #根据元素值删除元素,只会删除找到的第一个元素 list1.remove("hello") print(list1) #添加元素 list1.append("add") print(list1)
输出结果如下:
hello hello [10.1, True, 'hello'] [1, 'hello'] [1, 'hello', 10.1, True, 'hello', 10, True, False, 11.1, 'world'] [10, True, False, 11.1, 'world', 10, True, False, 11.1, 'world'] True 100 ['hello', 10.1, True, 'hello'] [10.1, True, 'hello'] [10.1, True, 'hello', 'add']
从上面的代码可以看出list中的元素是可以改变的,包括更新,删除和添加。
嵌套列表
再来看一下嵌套列表,嵌套列表只是看起来比较特殊而已,我们也可以把他当做简单的列表来看待。上面我们提到过,列表中可以存放任何不同数据类型的数据。那么如果存放的数据是一另一个列表,那么就变成了嵌套列表,这跟java中的多维数组是对应的。代码如下:list = [[1,2,3],4,5] print(list[0]) print(list[0][1])
输出结果如下:
[1, 2, 3] 2
列表函数
直接看代码:list = [9,4,5] #添加元素到列表末尾 list.append(5) print(list) #添加元素到指定下标,该位置以及之后的元素集体后移 list.insert(0, 0) print(list) #移除并返回列表最后一个元素 print(list.pop()) print(list) #删除具体元素 list.remove(4) print(list) #某元素出现的次数 print(list.count(5)) #某下标的元素 print(list.index(5)) #排序 list.sort() print(list) #反转 list.reverse() print(list) #复制 print(list.copy() is list)
输出结果如下:
[9, 4, 5, 5] [0, 9, 4, 5, 5] 5 [0, 9, 4, 5] [0, 9, 5] 1 2 [0, 5, 9] [9, 5, 0] False
元组
元组也是一种序列,和列表类似,不同之处在于元组元组一经创建,内容就不能在修改,不能添加数据和修改数据。元组的是通过逗号分割的数据,然后用一对小括号括起来表示。可以创建空的元组使用(),但是因为元组的数据不能修改,所以空的元组貌似没有什么意义:#创建元组 tup1 = (9,4,5) #如果元组只有一个元素,需要在后面添加一个逗号 tup2 = (1,) #元组的索引,分片,加法,乘法,和检查成员 print(tup1[0]) print(tup1[1:]) print(tup1 + tup2) print(tup2 * 2) print(4 in tup1) #某个元素出现的次数 print(tup1.count(5)) #某个元素出现的下标 print(tup1.index(4))
输出结果如下:
9 (4, 5) (9, 4, 5, 1) (1, 1) True 1 1
到这里python中常用的序列就over了,下面看一下,python剩下的两种数据结构,集合和字典。
集合
集合是一个不重复的元素的集,从这一点我们就可以看出,集合有一个重要的作用就是去除重复。另外集合之间还可以进行子集,父集,并集,交集,差集,以及对称差集运算。集合使用大括号{}括起来的结构,需要注意的是,如果要创建一个空的集合,那么必须使用set(),不能使用{},因为一对空的大括号创建的是字典,下一节会学到字典。python的集合就相当于java中的HashSet,下面看一下集合的代码:#创建集合 set1 = {1,2,3,4,1,2,3,4} set2 = {4,5,6,7,8,8,10} #从打印结果,我们可以看到,set1中去除了重复的元素 print(set1) #删除元素 set1.remove(1); print(set1) #删除并返回第一个元素 set1.pop(); print(set1) #如果存在元素则删除,不存在没有任何影响 set1.discard(100); #添加元素 set1.add(5); print(set1) #批量添加元素 set1.update([1,2,6,7]) print(set1) #并集的两种方式 print(set1.intersection(set2)) print(set1 & set2) #差集的两种方式 print(set1.difference(set2)) print(set1 - set2) #并集的两种方式 print(set1.union(set2)) print(set1 | set2) #对称差集的两种方式 print(set1.symmetric_difference(set2)) print(set1 ^ set2) #是否子集 print(set1.issubset(set2)) #是否父集 print(set1.issuperset(set2))
输出结果如下:
{1, 2, 3, 4} {2, 3, 4} {3, 4} {3, 4, 5} {1, 2, 3, 4, 5, 6, 7} {4, 5, 6, 7} {4, 5, 6, 7} {1, 2, 3} {1, 2, 3} {1, 2, 3, 4, 5, 6, 7, 8, 10} {1, 2, 3, 4, 5, 6, 7, 8, 10} {1, 2, 3, 8, 10} {1, 2, 3, 8, 10} False False
字典
python的字典,相当于java里的map,是一种键值映射结构,同样键不能重复,如果设置同样的键,那么后者会覆盖前者。键和值都可以是任意的python数据类型:#创建字典 dict = {"name":"chujinhui","age":"28"} print(dict["name"]) #修改 dict["age"] = 30 dict["school"] = "qinghua" print(dict["age"],dict["school"]) #删除 del dict["age"] print(dict) # dict[(1,2,3)] = "hello" print(dict)
输出结果如下:
chujinhui 30 qinghua {'school': 'qinghua', 'name': 'chujinhui'} {(1, 2, 3): 'hello', 'school': 'qinghua', 'name': 'chujinhui'}
相关文章推荐
- java程序员的大数据之路(9):MapReduce的类型
- JAVA程序员学python-1.变量及数据类型
- Java新手之路——Day03 Java语言基础组成_数据类型
- 我的python之路【第二篇】数据类型与方法
- 我的Python学习之路 Python的输入输出与基本数据类型
- Java程序员.回头学C/C++ 之 Java&C基本数据类型大对比
- 【Java Script 入门之路之数据类型和值】
- java和python中的string和int数据类型的转换
- python数据类型与c++,java数据类型区别
- Java新手之路——Day 04 数据类型转换
- java自学之路之数据类型
- 【重走Android之路】【Java面向对象基础(一)】数据类型与运算符
- python学习之路-3 初始python数据类型以及文件操作
- Java程序员从笨鸟到菜鸟之(四十四)细谈struts2(七)数据类型转换详解
- Java中基本数据类型的存储方式和相关内存的处理方式(java程序员必读经典)
- Java程序员从笨鸟到菜鸟之(四十四)细谈struts2(七)数据类型转换详解
- Java中基本数据类型的存储方式和相关内存的处理方式(java程序员必读经典)
- python 自动化之路 day 01.1 数据类型
- java程序员的python之路(条件,循环和迭代器)
- C\C#\Java\Python 基本数据类型比较