当前位置: 首页>前端>正文

跟我一起学Python(二)

一、编码

ASCII编码、Unicode编码、可变长编码”的UTF-8编码之间的由来

由于计算机是美国人发明的,因此,最早只有127个字符被编码到计算机里,这个编码表被称为ASCII编码,但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。你可以想得到的是,全世界有上百种语言,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。

Unicode应运而生。Unicode把所有语言都统一到一套编码里。如果统一成Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间。

于是乎又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。

二、字符串

在最新的Python 3版本中,字符串是以Unicode编码的

  • 单个字符的编码
    ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符:
>>> ord('中')
20013
>>> chr(25991)
'文'
如果知道字符的整数编码,还可以用十六进制这么写str:
>>> '\u4e2d\u6587'
'中文'
  • 由于Python的字符串类型是str,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes。
x = b'ABC'

以Unicode表示的str通过encode()方法可以编码为指定的bytes,例如:

>>> 'ABC'.encode('ascii')
b'ABC'

反过来从网络或磁盘上读取了字节流,要把bytes变为str,就需要用decode()方法:

  • 要计算str包含多少个字符,可以用len()函数:
>>> len('ABC')
3

len()函数计算的是str的字符数,如果换成bytes,len()函数就计算字节数:
例如:>>> len('中文'.encode('utf-8')) // 6 ; >>> len(b'ABC') //3;

由于Python源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这两行:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;
第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。
申明了UTF-8编码并不意味着你的.py文件就是UTF-8编码的,必须并且要确保文本编辑器正在使用UTF-8 without BOM编码:

三、格式化

>>> 'Hello, %s' % 'world'
'Hello, world'
>>> 'Hi, %s, you have $%d.' % ('Michael', 1000000)
'Hi, Michael, you have 00000.'

%运算符就是用来格式化字符串的。在字符串内部,%s表示用字符串替换,%d表示用整数替换,有几个%?占位符,后面就跟几个变量或者值,顺序要对应好。如果只有一个%?,括号可以省略。

常见的占位符有:%d 整数 / %f 浮点数 /%s 字符串 /%x 十六进制整数

  • 格式化整数和浮点数还可以指定是否补0和整数与小数的位数:
print('%2d-%02d' % (3, 1))    // 3-01      2d代表两位整数,但由于第一个2d前面无0,所以 3的前面未补0 , 1的前面补0
print('%.2f' % 3.1415926)    //3.14        保留了两位小数

有些时候,字符串里面的%是一个普通字符怎么办?这个时候就需要转义,用%%来表示一个%:

  • format() //另一种格式化字符串的方法
>>> 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
'Hello, 小明, 成绩提升了 17.1%'

四、数据类型

list

list是一种有序的集合,是一种数据类型。类似JS里的数组

  • 注意:当超出索引值的时候Python会报IndexError错误
  • 可以用-1做索引,直接获取最后一个元素,如: classmates[-1] //'Tracy',以此类推,可以获取倒数第2个、倒数第3个:
  • len()函数可以获得list元素的个数,如:len(classmates)
  • classmates.insert(1, 'Jack') 往指定位置插入元素
  • classmates.append('Adam')往末尾追加元素
  • classmates.pop(1) 删除指定位置的元素
  • classmates[1] = 'Sarah';把某个元素替换成别的元素
  • list元素也可以是另一个list ;s = ['python', 'java', ['asp', 'php'], 'scheme']
  • list里面的元素的数据类型也可以不同

[1] + [2] + [3] == [1,2,3]

tuple

tuple是另一种有序的集合,是一种数据类型。tuple和list非常类似,但是tuple一旦初始化就不能修改
classmates = ('Michael', 'Bob', 'Tracy')
要定义一个只有1个元素的tuple,方式如下:

#正确的
 t = (1,)  //(1,)
#错误的  定义的不是tuple,是1这个数!此时()为数学公式中的小括号
 t = (1)//1

dict(类似Object)

 d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
d['Michael']       #95
d['Adam'] = 67
d['Adam']          #67
a[' aaaa']   #报错,但是如果是JS不报错,输出undefined

判断key 在不在dict里面

  • in
 'Thomas' in d  #False
  • get()
d.get('Thomas') #如果key不存在,可以返回None

删除key

 d.pop('Bob')

编写一个Dict类,这个类的行为和dict一致,但是可以通过属性来访问,

>>> d = Dict(a=1, b=2)
>>> d['a']
1
>>> d.a
1

set

是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。

 s = set([1, 2, 3]) #s {1, 2, 3}
  • add()
    add(key)方法可以添加元素到set中,可以重复添加,但不会有效果:
  • remove()
    remove(key)方法可以删除元素:
  • set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}

五、切片 方法

list

取前N个元素,也就是索引为0-(N-1)的元素,L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3;如果第一个索引是0,还可以省略:表示为L[:3],也支持 L[-2:],表示从倒数第二个开始取至最后一个。

L = list(range(100))
 L[:10:2] #前10个数,每两个取一个:
 L[::5] #所有数,每5个取一个:[0, 2, 4, 6, 8]
 L[:] #只写[:]就可以原样复制一个list:[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]

tuple

tuple类似,唯一区别是切片后仍为tuple

>>> (0, 1, 2, 3, 4, 5)[:3]
(0, 1, 2)

字符串

字符串也类似,唯一区别是切片后仍为字符串

>>> 'ABCDEFG'[:3]
'ABC'

用切片重写str的strim()方法

def trim(s):
    if len(s) == 0:
        return s
    elif s[0] == ' ':
        return (trim(s[1:]))
    elif s[-1] == ' ':
        return (trim(s[:-1]))
    return s
print(trim("  23a  "))

六、if和循环

条件判断

age = 3
if age >= 18:
    print('your age is', age)
    print('adult')
else:
    print('your age is', age)
    print('teenager')

也可以用elif做更细致的判断

例子

s = input('birth: ')
birth = int(s)  # input()返回的数据类型是str
if birth < 2000:
    print('00前')
else:
    print('00后')

循环

for ... in ...

names = ['Michael', 'Bob', 'Tracy']
for name in names:
    print(name)

while(和JS一样)

break和continue的区别:

  • break的作用是提前结束循环。
  • continue的作用是提前结束本轮循环,并直接开始下一轮循环。

七、其他特性

迭代

如何判断一个对象是可迭代对象

from collections import Iterable
print(isinstance('abc', Iterable)) # str是否可迭代

如果你的Python在3.8+,则会有警告提示:
DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
from collections import Iterable

Python内置的enumerate函数可以把一个list变成索引-元素对

for i, value in enumerate(['A', 'B', 'C']):
...     print(i, value)
...
0 A
1 B
2 C
#for循环里,同时引用了两个变量
for x, y in [(1, 1), (2, 4), (3, 9)]:
...     print(x, y)
...
1 1
2 4
3 9

问题:请用迭代的方法查找一个list里面的最小值和最大值,并返回一个tuple

def findMinAndMax(L):
    min = L[0]
    max = L[0]
    for i in L[1:]:
        if i>max:
            max = i
        elif i< min:
            min = i
    return(min,max)

print(findMinAndMax([6,2,3,4]))

列表生成式

list(range(1, 11)) 得到 list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

[x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
[m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
#循环dict的items()来生成list
>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.items()]
['y=B', 'x=A', 'z=C']

问题:将一个单项类型不都为字符串的list里面所有字符串转化为小写字母,并生成新的list

L =  ['Hello', 'World', 18, 'Apple', None]
print([s.lower() for s in L if isinstance(s, str)])

生成器 generator

创建一个generator
1.把一个列表生成式的[]改成(),就创建了一个generator:

>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>

但此时我们怎么打印出generator的每一个元素呢?可以通过next()函数获得generator的下一个返回值。

>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
...
#或者
>>> g = (x * x for x in range(10))
>>> for n in g: #因为generator也是可迭代对象:所以也可以使用for循环
...     print(n)
...

斐波拉契数列

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
        a, b = b, a + b
        n = n + 1
    return 'done'

要把fib函数变成generator,只需要把print(b)改为yield 就可以了:

注意:
a.对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令,for循环随之结束。
b.如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator

问题:把每一行看做一个list,试写一个generator,不断输出下一行的list


跟我一起学Python(二),第1张
杨辉三角
def yhTriangle(n):
    l, index = [1], 0
    while index < n:
        yield l
        l = [1] + [l[i] + l[i + 1] for i in range(len(l) - 1)] + [1]
        index += 1
l = yhTriangle(3)
for item in l:
    print(item)

迭代器

可以直接作用于for循环的对象统称为可迭代对象:Iterable。
如:list、tuple、dict、set、str、generator,包括生成器和带yield的generator function。
可以使用isinstance()判断一个对象是否是Iterable对象:

>>> from collections import Iterable
>>> isinstance([], Iterable)
True

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。
可以使用isinstance()判断一个对象是否是Iterator对象:它们表示一个惰性计算的序列;


https://www.xamrdz.com/web/2zz1911016.html

相关文章: