python3和Python2的区别

一、print函数

python2 的 print 声明已经被 print() 函数取代了,这意味着我们必须包装我们想打印在小括号中的对象

二、通过input()解析用户的输入

  • python3中input得到的为str,python3中没有raw_input
  • Python2的input的到的为int型,Python2的raw_input得到的为str类型

三、整除

  • Python3中/表示真除,%表示取余,//表示地板除(结果取整)
  • Python2中/表示根据除数被除数小数点位得到结果,//同样表示地板除)

python2

1     from platform import python_version
2     print 'Python', python_version()
3     print '5 / 3 =', 5 / 3
4     print '3 // 2 =', 3 // 2
5     print '3 / 2.0 =', 3 / 2.0
6     print '3 // 2.0 =', 3 // 2.0

Python 2.7.10
5 / 3 = 1
3 // 2 = 1
3 / 2.0 = 1.5
3 // 2.0 = 1.0

python3

1     from platform import python_version
2     print('Python', python_version())
3     print('5 / 3 =', 5 / 3)
4     print('3 // 2 =', 3 // 2)
5     print('3 / 2.0 =', 3 / 2.0)
6     print('3 // 2.0 =', 3 // 2.0)

Python 3.6.0
5 / 3 = 1.6666666666666667
3 // 2 = 1
3 / 2.0 = 1.5
3 // 2.0 = 1.0

四、xrange模块

python2 : range( 0, 4 ) 结果 是 列表 [0,1,2,3 ]
python3改为:list( range(0,4) )
python2原 : xrange( 0, 4 ) 适用于 for 循环的变量控制

python3改为:range(0,4)

 

  • python3
    在 Python 3 中,range() 是像 xrange() 那样实现以至于一个专门的 xrange() 函数都不再存在(在 Python 3 中xrange() 会抛出命名异常)。
  • python2
    在 Python 2 中 xrange() 创建迭代对象的用法是非常流行的。比如: for 循环或者是列表/集合/字典推导式

    这个表现十分像生成器(比如。“惰性求值”)。但是这个 xrange-iterable 是无穷的,意味着你可以无限遍历。由于它的惰性求值,如果你不仅仅遍历它一次,xrange() 函数 比 range() 更快(比如 for 循环)。尽管如此,对比迭代一次,不建议你重复迭代多次,因为生成器每次都从头开始。

五、字符串

原: 字符串以 8-bit 字符串存储
改为: 字符串以 16-bit Unicode 字符串存储

 

六、try except 语句的变化

在 Python 3 中处理异常也轻微的改变了,在 Python 3 中我们现在使用 as 作为关键词。
捕获异常的语法由 except exc, var 改为 except exc as var。

使用语法except (exc1, exc2) as var可以同时捕获多种类别的异常。 Python 2.6已经支持这两种语法。
    1. 在2.x时代,所有类型的对象都是可以被直接抛出的,在3.x时代,只有继承自BaseException的对象才可以被抛出。
    2. 2.x raise语句使用逗号将抛出对象类型和参数分开,3.x取消了这种奇葩的写法,直接调用构造函数抛出对象即可。
在2.x时代,异常在代码中除了表示程序错误,还经常做一些普通控制结构应该做的事情,在3.x中可以看出,设计者让异常变的更加专一,只有在错误发生的情况才能去用异常捕获语句来处理。

 

1     原: try:
2         ......
3       except Exception, e :
4         ......
5     改为
6       try:
7         ......
8       except Exception as e :
9         ......

 

七、打开文件

    原: file( ..... )
    或 open(.....)
    改为:
    只能用 open(.....)

 

八、bytes 数据类型 -- 新增

1)Py3.X去除了long类型,现在只有一种整型——int,但它的行为就像2.X版本的long
2)新增了bytes类型,对应于2.X版本的八位串,定义一个bytes字面量的方法如下:
1     >>> b = b'china'
2     >>> type(b)
3     <type 'bytes'>
str对象和bytes对象可以使用.encode() (str -> bytes) or .decode() (bytes -> str)方法相互转化
1     >>>s = b.decode()
2     >>> s
3     'china'
4     >>> b1 = s.encode()
5     >>> b1
6     b'china'
A bytes object is an immutable array. The items are 8-bit bytes, represented by integers in the range 0 <= x < 256.
bytes 可以看成是“字节数组”对象,每个元素是 8-bit 的字节,取值范围 0~255。
由于在 python 3.0中字符串以 unicode 编码存储,当写入二进制文件时,字符串无法直接写入(或读取),必须以某种方式的编码为字节序列后,方可写入。

(一)字符串编码(encode) 为 bytes

    例: s = "张三abc12"
    b = s.encode( 编码方式)
    # b 就是 bytes 类型的数据
    # 常用的编码方式为 : "uft-16" , "utf-8", "gbk", "gb2312", "ascii" , "latin1" 等
    # 注 : 当字符串不能编码为指定的“编码方式”时,会引发异常

 

(二) bytes 解码(decode)为字符串

1      s = "张三abc12"
2     b = s.encode( "gbk") # 字符串 s 编码为 gbk 格式的字节序列
3     s1 = b.decode("gbk") # 将字节序列 b以gbk格式 解码为字符串
4     # 说明,当字节序列不能以指定的编码格式解码时会引发异常

 

(三)使用方法举例

 1     #coding=gbk
 2     f = open("c:\\1234.txt", "wb")
 3     s = "张三李四abcd1234"
 4     # -------------------------------
 5     # 在 python2.4 中我们可以这样写:
 6     # f.write( s )
 7     # 但在 python 3.0中会引发异常
 8     # -------------------------------
 9     b = s.encode("gbk")
10     f.write( b )
11     f.close()
12     input("?")

 

读取该文件的例子:

 1     #coding=gbk
 2     f = open("c:\\1234.txt", "rb")
 3     f.seek(0,2) #定位至文件尾
 4     n = f.tell() #读取文件的字节数
 5     f.seek(0,0) #重新定位至文件开始处
 6     b = f.read( n )
 7     # ------------------------------
 8     # 在 python 2.4 中 b 是字符串类型
 9     # 而 python 3.0 中 b 是 bytes 类型
10     # 因此需要按指定的编码方式确码
11     # ------------------------------
12     s = b.decode("gbk")
13     print ( s )
14     # ------------------------------
15     # 在 python 2.4 中 可以写作 print s 或 print ( s )
16     # 要 python 3.0 中 必须写作 print ( s )
17     # ------------------------------
18     f.close()
19     input("?")

 

运行后应显示:
张三李四abcd1234

(四) python3中bytes序列,一但形成,其内容是不可变的
例:

1     s="ABCD"
2     b=s.encode("gbk")
3     print b[0] # 显示 65
4     b[0] = 66
5     # 执行该句,出现异常: 'bytes' object does not support item assignment

九、chr( K ) 与 ord( c )

ord()函数主要用来返回对应字符的ascii码,chr()主要用来表示ascii码对应的字符他的输入时数字,可以用十进制,也可以用十六进制
python 2.4.2以前
    chr( K ) 将编码K 转为字符,K的范围是 0 ~ 255
    ord( c ) 取单个字符的编码, 返回值的范围: 0 ~ 255
python 3.0
    chr( K ) 将编码K 转为字符,K的范围是 0 ~ 65535
    ord( c ) 取单个字符的编码, 返回值的范围: 0 ~ 65535

 

十、字节数组对象bytearray -- 新增

(一) 初始化

    a = bytearray( 10 )
    # a 是一个由十个字节组成的数组,其每个元素是一个字节,类型借用 int
    # 此时,每个元素初始值为 0

 

(二) 字节数组 是可变的

    a = bytearray( 10 )
    a[0] = 25
    # 可以用赋值语句更改其元素,但所赋的值必须在 0 ~ 255 之间

(三) 字节数组的切片仍是字节数组
(四) 字符串转化为字节数组

1     #coding=gbk
2     s ="你好"
3     b = s.encode( "gbk") # 先将字符串按某种“GBK”编码方式转化为 bytes
4     c = bytearray( b ) #再将 bytes 转化为 字节数组
5     # 也可以写作
6     c = bytearray( "你好", "gbk")
View Code

(五) 字节数组转化为字符串

1      c = bytearray( 4 )
2     c[0] = 65 ; c[1]=66; c[2]= 67; c[3]= 68
3     s = c.decode( "gbk" )
4     print ( s )
5     # 应显示: ABCD

(六) 字节数组可用于写入文本文件

 1     #coding=gbk
 2     f = open("c:\\1234.txt", "wb")
 3     s = "张三李四abcd1234"
 4     # -------------------------------
 5     # 在 python2.4 中我们可以这样写:
 6     # f.write( s )
 7     # 但在 python 3.0中会引发异常
 8     # -------------------------------
 9     b = s.encode("gbk")
10     f.write( b )
11     # 或者
12     c=bytearray( s,"gbk")
13     f.write( c )
14     f.close()
15     input("?")

 

十一、“import thread”问题

2.x中的模块thread在3.x中编程"_thread"(需要在前面加一个下划线).否则会出现“ImportError: No module named thread

 

十二、不等运算符

Python 2.x中不等于有两种写法 != 和 <>
Python 3.x中去掉了<>, 只有!=一种写法,还好,我从来没有使用<>的习惯

 

十三、去掉了repr表达式``

Python 2.x 中反引号``相当于repr函数的作用
Python 3.x 中去掉了``这种写法,只允许使用repr函数,这样做的目的是为了使代码看上去更清晰么?不过我感觉用repr的机会很少,一般只在debug的时候才用,多数时候还是用str函数来用字符串描述对象。

 

十四、dict

dict的.keys()、.items 和.values()方法返回迭代器,而之前的iterkeys()等函数都被废弃。同时去掉的还有 dict.has_key(),用 in替代它吧 。

 

十五、map、filter 和 reduce

这三个函数号称是函数式编程的代表。在 Python3.x 和 Python2.x 中也有了很大的差异。
首先我们先简单的在 Python2.x 的交互下输入 map 和 filter,看到它们两者的类型是 built-in function(内置函数):

 

python2.x它们输出的结果类型都是列表
1     >>> map(lambda x:x *2, [1,2,3])
2     [2, 4, 6]
3     >>> filter(lambda x:x %2 ==0,range(10))
4     [0, 2, 4, 6, 8]
5     >>>
但是在Python 3.x中它们却不是这个样子了:
1     >>> map
2     <class 'map'>
3     >>> map(print,[1,2,3])
4     <map object at 0x10d8bd400>
5     >>> filter
6     <class 'filter'>
7     >>> filter(lambda x:x % 2 == 0, range(10))
8     <filter object at 0x10d8bd3c8>
9     >>>

 

首先它们从函数变成了类,其次,它们的返回结果也从当初的列表成了一个可迭代的对象, 我们尝试用 next 函数来进行手工迭代:
 1     >>> f =filter(lambda x:x %2 ==0, range(10))
 2     >>> next(f)
 3     0
 4     >>> next(f)
 5     2
 6     >>> next(f)
 7     4
 8     >>> next(f)
 9     6
10     >>>

 

对于比较高端的 reduce 函数,它在 Python 3.x 中已经不属于 built-in 了,被挪到 functools 模块当中
1     >>> import functools
2     >>> b = functools.reduce(lambda x, y: x + y, [1, 3, 4, 5])
3     >>> print(b)
4     13
5     >>>

 

十六、cmp()函数的新函数(gt,ge,eq,le,lt)

Python3中已经不能使用cmp()函数了,被如下五个函数替代:
1     import operator #首先要导入运算符模块
2     operator.gt(1,2) #意思是greater than(大于)
3     operator.ge(1,2) #意思是greater and equal(大于等于)
4     operator.eq(1,2) #意思是equal(等于)
5     operator.le(1,2) #意思是less and equal(小于等于)
6     operator.lt(1,2) #意思是less than(小于)

 

十七、sort,sorted

Sort函数是list列表中的函数,而sorted可以对list或者iterator进行排序。
Python3.x和Python2.x的sorted函数有点不太一样,少了cmp参数。下面本渣渣主要基于Python2.x的sorted函数进行讲解,Python3.x直接忽略cmp这个参数即可,为了保证代码通用性,不建议大家在今后的编程中使用cmp参数

下面我们使用help来查看他们的用法及功能:

 

python2:

1     >>> help(list.sort)
2     Help on method_descriptor:
3     sort(...)
4     L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
5     cmp(x, y) -> -1, 0, 1
6     >>> help(sorted)
7     Help on built-in function sorted in module __builtin__:
8     sorted(...)
9     sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list

 

python3:

 1 >>> help(list.sort)
 2 Help on method_descriptor:
 3 sort(...)
 4   L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*
 5 >>> help(sorted)
 6 Help on built-in function sorted in module builtins:
 7 sorted(iterable, key=None, reverse=False)
 8   Return a new list containing all items from the iterable in ascending order.
 9   A custom key function can be supplied to customize the sort order, and the
10   reverse flag can be set to request the result in descending order.

 

用sort函数对列表排序时会影响列表本身,而sorted不会。两者用法差不多。

以sorted为例,sorted(iterable,cmp,key,reverse)

参数: 
- iterable可以是list或者iterator; 
- cmp是带两个参数的比较函数; 
- key 是带一个参数的函数; 
- reverse为False或者True;

 

举例说明:
(1)用cmp函数排序:

1     >>> list1 = [('david', 90), ('mary',90), ('sara',80),('lily',95)]
2     >>> sorted(list1,cmp = lambda x,y: cmp(x[0],y[0]))
3     [('david', 90), ('lily', 95), ('mary', 90), ('sara', 80)]
4     >>> sorted(list1,cmp = lambda x,y: cmp(x[1],y[1]))
5     [('sara', 80), ('david', 90), ('mary', 90), ('lily', 95)]

 

(2)用key函数排序:

1     >>> list1 = [('david', 90), ('mary',90), ('sara',80),('lily',95)]
2     >>> sorted(list1,key = lambda list1: list1[0])
3     [('david', 90), ('lily', 95), ('mary', 90), ('sara', 80)]
4     >>> sorted(list1,key = lambda list1: list1[1])
5     [('sara', 80), ('david', 90), ('mary', 90), ('lily', 95)]

 

(3)用reverse排序:

1  >>> sorted(list1,reverse = True)
2     [('sara', 80), ('mary', 90), ('lily', 95), ('david', 90)]

 

(4)用operator.itemgetter函数排序:

1     >>> from operator import itemgetter
2     >>> sorted(list1, key=itemgetter(1))
3     [('sara', 80), ('david', 90), ('mary', 90), ('lily', 95)]
4     >>> sorted(list1, key=itemgetter(0))
5     [('david', 90), ('lily', 95), ('mary', 90), ('sara', 80)]

 

介绍operator.itemgetter函数:
operator.itemgetter函数获取的不是值,而是定义了一个函数。该函数是C语言实现,比python速度快。

1     >>> import operator
2     >>> a = [1,2,3]
3     >>> b = operator.itemgetter(0)
4     >>> b(a)
5     1

 

(5)多级排序:

1         >>> sorted(list1, key=itemgetter(0,1))
2         [('david', 90), ('lily', 95), ('mary', 90), ('sara', 80)]

 

posted @ 2018-06-15 15:25  Paul7777  阅读(762)  评论(0编辑  收藏  举报