java程序员的python之路(数据类型)

环境

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'}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值