最近会将 Python 的基础知识进行梳理归纳,这算是第一篇吧。小白刚入门,有错误或不详实的地方还请大家斧正。
先罗列一下Python提供的基本数据类型:数值(整型、浮点型、复数、布尔型等)、字符串、列表、元组、字典、集合等,将它们简单分类如下:
数值(Numbers)
numbers:列出了一些简单的例子
361, -361, 0, 66666# 整型 --> int()
3.61, 3.14e-6, 0.0# 浮点型 --> float()
3+6j, 3.0+6.0j, 6j# 复数 --> complex([real[, imag]])
0b101010 # 二进制 --> bin()
0o177# 八进制 --> oct()
0x9ff# 十六进制 --> hex()
# 常见操作
+, -, *, /, //, %, **# / 结果是浮点数,// 结果只取整数部分
&, |, ^, <<, >># 位操作,与,或,异或,左移,右移
bool:调用bool()可以检查变量的真假值True或False。
if语句通过判断布尔类型来控制程序的执行路径,同时在 Python 中数据有隐式的真假值,可以使代码变得简短有效,如下
字符串(String)
首先,我们定义一个s='python'语句,它在计算机中的执行顺序是先在内存中创建一个字符串python,在程序栈寄存器中创建一个变量s,最后把python的地址赋给s 。
再来看看字符串的一些常见操作
"""字符串"""# 多行字符串,一般用于文件说明和函数说明,可使用__doc__输出
s = '优雅的Python'
# 切片
s[0], s[-1], s[3:], s[::-1]# '优', 'n', 'Python', 'nohtyP的雅优'
# 替换,还可以使用正则表达式替换
s.replace('Python', 'Java')# '优雅的Java'
# 查找,find()、index()、rfind()、rindex()
s.find('P')# 3, 返回第一次出现的子串的下标
s.find('h', 2)# 6, 设定下标2开始查找
s.find('23333')# -1, 查找不到返回-1
s.index('y')# 4, 返回第一次出现的子串的下标
s.index('23333')# 不同与find(), 查找不到会抛出异常
# 转大小写, upper()、lower()、swapcase()、capitalize()、istitle()、isupper()、islower()
s.upper()# '优雅的PYTHON'
s.swapcase()# '优雅的pYTHON', 大小写互换
s.istitle()# True
s.islower()# False
# 去空格,strip()、lstrip()、rstrip()
# 格式化
s1 = '%s%s' % ('Windrivder', 21)# 'Windrivder 21'
s2 = '{}, {}'.format(21, 'Windridver')# 推荐使用format格式化字符串
s3 = '{0}, {1}, {0}'.format('Windrivder', 21)
s4 = '{name}: {age}'.format(age=21, name='Windrivder')
# 连接与分割,使用 + 连接字符串,每次操作会重新计算、开辟、释放内存,效率很低,所以推荐使用join
l = ['2017', '03', '29', '22:00']
s5 = '-'.join(l)# '2017-03-29-22:00'
s6 = s5.split('-')# ['2017', '03', '29', '22:00']
# 还有一些常用的,这里只列出来
S.endswith() # 字符串是否以给定字符串结尾
S.startswith() # 字符串是否以给定字符串开始
S.isalnum() # 是否全是字母和数字
S.isalpha() # 是否全是字母
S.isspace() # 是否全是空白字符
S.center(width, [fillchar]) # 中间对齐
S.ljust(width,[fillchar]) # 左对齐,默认是空格补全
S.rjust(width,[fillchar]) # 右对齐
S.count(substr, [start, [end]])# 计算substr在S中出现的次数
S.splitlines([keepends]) # 按行分割成list,keepends是一个bool值,如果为真每行后而会保留行分割符。
以上是一些常见的操作,当然还有一个没有列出来,这里想单独拿来谈谈,就是 Python3 字符串的编码:ASCII 编码出现最早,只有大小写英文字母、数字和一些符号等127个字符,为了实现多语言表示,如中文的GB2312编码,日文的Shift_JIS编码等,Unicode 孕育而生,它将所有语言都统一到一套编码中;
在 Python3 中所有字符串在内存中均是 Unicode 保存;
当需要将文件保存到外设或进行网络传输时,就要进行编码转换,将字符转换为字节,以提高效率
# encode 将字符转换为字节
>>> str = '优雅的Python'
>>> str.encode()# 默认编码是 UTF-8
b'\xe4\xbc\x98\xe9\x9b\x85\xe7\x9a\x84Python'
>>> str.encode('gbk')
b'\xd3\xc5\xd1\xc5\xb5\xc4Python'
# decode 将字节转换为字符
>>> b'\xe4\xbc\x98\xe9\x9b\x85\xe7\x9a\x84Python'.decode()
'优雅的Python'
>>> b'\xd3\xc5\xd1\xc5\xb5\xc4Python'.decode('gbk')
'优雅的Python'
在 Python3 中,内存中的 Unicode 字符用 str 对象表示,对应于的,Python3 使用了一种全新的数据类型来表示字节,就是 bytes,所以 encode 转换后的字节流就不是 str 对象,而是 bytes 字节对象,它当然支持分片、索引、基本数值运算等操作,但 str 与 bytes 类型的数据不能进行+操作。
来看看 bytes 数据类型的定义:
>>> byt = b'优雅的Python'
File "", line 1
SyntaxError: bytes can only contain ASCII literal characters.
>>> byt = b'Python'
>>> type(byt)
从上述例子中可以看出 bytes 对象不能由超出 ASCII 码范围的字符组成,只接受 ASCII 码这个范围的字符。
>>> u'a'
'a'
>>> '\u0061'
'a'
>>> '中'.encode('unicode-escape')
b'\\u4e2d'
>>> b'@Aa'
b'@Aa'
>>> b'\x40\x41\x61'
b'@Aa'
>>> #-*- coding:utf-8 -*-
...
>>>
同样,从上面的例子我们还可以总结出一些坑爹的东西:Unicode 码在 Python3 中有两种表示方式,u'字符串'和\u四位十六进制数;区分r'字符串' ,是表示不转义的原始字符串
将字符直接以 Unicode 码保存使用unicode-escape
在 Python 的交互式环境中,输出 bytes 对象时,可按 ASCII 码表示,或按十六进制\x表示
在 Python 头声明#-*- coding:utf-8 -*-,是告诉 Python 编译器按utf-8的方式读取,这个声明并不能将 Python 文件本身保存成utf-8,这时候需要借助文本编辑器保存文件编码。编码部分我的理解就是这些了,感觉还是没有将编码问题总结清楚(无奈),期待各位的讲解
列表(List)
Python 可使用语法糖[]表示列表,其中的元素可以是任何类型,以顺序存储的方式动态储存数据:
# 定义
L = []# 推荐方式
L = list()
L = ['Windrivder', 21, {'name': 'xiaoming'}]
# 多重赋值技巧
name, age, other = L
# 列表切片参考str
# 常用方法
L.append('a')# ['Windrivder', 21, {'name': 'xiaoming'}, 'a']
L.pop()# ['Windrivder', 21, {'name': 'xiaoming'}],还可以指定下标删除元素
L.extend(L1)# 合并列表 L1
L.insert(1, 'a')# 在下标为1的位置插入'a'
L.index('a')# 同字符串的index()
L.remove('a')# 删除操作
L.count('a')# 求某个值的个数
L.reverse()# 反转
L = [2, 4, -1, 9, -5, 6]
L.sort()# sort()排序,使用非常灵活
L.sort(reverse=True) # 反序
L.sort(key=abs)# 传入函数关键字作为排序规则
for l1, l2 in zip(['windrivder', 21], ['jack', 22]):# zip 同时遍历两个列表
print('{} --> {}'.format(l1, l2))
for index, value in enumerate(L):# enumerate 带索引遍历列表
print('{} --> {}'.format(index, value))
# 列表生成式
L = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
r = [sum(L) for l in L]# [6, 15, 24]
L = [a for a in range(0, 10) if a % 2 == 0]# [0, 2, 4, 6, 8]
元组(Tuple)
元组与列表不同的是,元组是不可变类型(immutable),不能对元素进行修改,但内存可以明确知道需要分配多少空间给元组
# 定义
t = ()
t = tuple()
t = (1,) # 定义一个元素时,需要与(1)-->int区分开
t = ('Windrivder', 21, {'name': 'xiaoming'})
# 没有列出更多的方法,可以使用 tuple.__dir__() 查看
t.index(21) # 1
字典(Dictionaries)
字典是通过键值对的方式进行存储,占用大量的内存而获得极快的查找和插入速度,而列表刚好相反,查找和插入速度随着元素的增加而变慢,但占用的内存较小。字典虽然是可变类型,但因为它的 value 的位置是根据 key 计算出来的,因此 key 必须是不可变对象,这样才能确保字典的正确使用。
# 定义
d = {}
d = {'windrivder': 21, 'other': {'jack': 22}} # 嵌套字典
d = dict(name='windrivder', age=21)
d = dict([('name', 'windrivder'), ('age', 21)]) # {'name': 'windrivder', 'age': 21}
d = dict(zip(['name', 'age'], ['windrivder', 21]))
# 常用方法
d.keys(), d.values(), d.items()# 分别遍历键、值、键值对
d.setdefault(key[, value])# 为字典的某一项设置默认值
d.get(key, default)# 获取字典中的某个值
d.update(newd)# 合并字典,此方式效率较高
d.pop(key, [d]) # 删除字典中键值为key的项,返回键值为key的值,如果不存在,返回默认值d,否则抛出异常
d.popitem()# 随机删除某一项键值对,还可以使用关键字 del
d = {k: v for (k, v) in zip(['name', 'age'], ['windrivder', 21])}
集合(Set)
集合与list类似,但集合中不允许有重复的元素,普通集合是可变的,Frozenset是不可变的,我们可以利用集合的特性消除重复元素或做并、交、差等数学操作
a = set()
b = set([1, 2, 3])
# 平时使用到的时候不多,所以没有列出
a.add(frozenset(b))
自定义数据类型
Python 允许通过继承去自定义数据类型,很多第三方库或框架都有类似的应用,这里简单实现了一个供参考:
class CustomDict(dict):
'''Simple dict but support access as x.y style.'''
def __init__(self, names=(), values=(), **kw):
super(CustomDict, self).__init__(**kw)
for k, v in zip(names, values):
self[k] = v
def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(
r"'CustomDict' object has no attribute '%s'" % key)
def __setattr__(self, key, value):
self[key] = value暂时只想到这么多了,以后随着学习的深入再来修改补充吧。
下一篇准备总结Python对函数式编程的支持。