您的位置:首页 > 编程语言 > Python开发

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
逻辑运算符&& , | |
位运算符& , | , ! , ^ , ~ , << , >> , >>>
这些运算符的含义,就不再一一说了,在下面代码注释部分,会简单介绍一下。下面我们一一验证这些运算符在python中的支持,先来看赋值运算符,python对上面提到的赋值运算符都支持,代码如下:

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
大致上和java还是差不多的,需要注意的就是算数运算符的幂运算和整除运算,以及逻辑运算符的写法,还有就是多出来的成员运算符和身份运算符。

序列

在说字符串之前,我们需要先了解一下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'}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python