Python基础I---常用数据类型

这篇博客主要是阅读python之旅 时做的笔记。提取出最主要的知识点,供个人在以后中快速查阅。

下面是该书的主要脉络。
这里写图片描述

基础

字符编码

ASCII,Unicode以及UTF-8是较为常用的三种字符编码。
简单来说ASCII占一个字符,只规定了128个字符,但是Unicode是四个字节的,如果表示某些只要一个字节的字符,显然就浪费存储空间。因此在Unicode的基础上,人们开发出了UTF-16,UTF-32和UTF-8。
UTF-8是用一个字节到四个字节来表示字符。 在UTF-8中,ASCII字符仍旧用一个字节表示,阿拉伯文、希腊文等使用两个字符表示,常用汉字用三个字符表示。

python的默认编码

  • python2:ASCII
>>> import sys
>>> sys.getdefaultencoding()
'ascii'
  • python3: UTF-8
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'

python2的字符类型

这里写图片描述
简单来说python2有两种字符串类型,str和unicode,两种类型可以用decode和encode相互转换。Unicode类型的字符串定义前面加个u,比如 u’小兵’

>>> '中文'.decode('utf-8')
u'\u4e2d\u6587'
>>> u'中文'.encode('utf-8')
'\xe4\xb8\xad\xe6\x96\x87'

UnicodeEncodeError & UnicodeDecodeError 根源

用 Python2 编写程序的时候经常会遇到 UnicodeEncodeError 和 UnicodeDecodeError,它们出现的根源就是如果代码里面混合使用了 str 类型和 unicode 类型的字符串,Python 会默认使用 ascii 编码尝试对 unicode 类型的字符串编码 (encode),或对 str 类型的字符串解码 (decode),这时就很可能出现上述错误。

  • 在进行同时包含str 类型和 unicode 类型的字符串操作时,Python2 一律都把 str 解码(decode)成 unicode 再运算,这时就很容易出现 UnicodeDecodeError。
    解决方法是直接用指定’utf-8’编码,
>>> s = '你好'                 # str 类型,utf-8 编码
>>> u = u'世界'
>>>
>>> s.decode('utf-8') + u     # 显示指定 'utf-8' 进行转换
u'\u4f60\u597d\u4e16\u754c'   # 注意这不是错误,这是 unicode 字符串
  • 如果函数或类等对象接收的是 str 类型的字符串,但你传的是 unicode,Python2 会默认使用 ascii 将其编码成 str 类型再运算,这时就很容易出现 UnicodeEncodeError。

raw_input

raw_input只接受str类型的字符串

>>> name = raw_input('输入你的姓名:')
输入你的姓名: 小明
>>> name
'\xe5\xb0\x8f\xe6\x98\x8e'
>>> type(name)
<type 'str'>

怎样让输入的字符串变成Unicode的呢?

>>> name = raw_input(u'输入你的姓名: '.encode('utf-8')).decode('utf-8') # 推荐
输入你的姓名:  小明
>>> name
u'\u5c0f\u660e'
>>> type(name)
<type 'unicode'>

输入

Python2 提供了 input,raw_input,print 等用于输入输出,但在 Python3 中发生了一些改变,raw_input 已经没有了,input 的用法发生了变化,print 也从原来的语句变成了一个函数。本文将对这两种情况进行介绍。

python2

废话不多说,一句话raw_input就是将所有的输入都转换成一个字符串
而如果用input的话,输入数字就是数字的类型,输入字符串得用’ ‘啊啊啊。

python3

python3中的input就是python2的raw_input,当然想要用python2的input就得这样
eval(input()),就是将字符串str当成有效的表达式来求值并返回计算结果

输出

python2中,print时可加可不加括号。python3中就一定得加括号。

格式化输出

>>> s = 'hello'
>>> l = len(s)
>>> print('the length of %s is %d' % (s, l))
the length of hello is 5
>>>
>>> pi = 3.14159
>>> print('%10.3f' % pi)     # 字段宽度 10,精度 3
     3.142
>>> print('%010.3f' % pi)    # 用 0 填充空白
000003.142
>>> print('%+f' % pi)        # 显示正负号
+3.141590

换行输出

print 默认是换行输出的,如果不想换行,可以在末尾加上一个 `,’,比如:

>>> for i in range(0, 3):
...     print i
...
0
1
2
>>> for i in range(0, 3):
...     print i,           # 加了 ,
...
0 1 2                      # 注意会加上一个空格

常用数据类型

总说

一般来说总说很重要。。
简单来说python中主要有5种数据类型。当然咯,就是 列表,元组,字符串,字典和集合。
序列类型: 列表、元组、字符串
其他类型:字典和集合

其实就是一句话:只要是序列就有公共的通用操作:
- 索引
- 分片
- 迭代
- 加
- 乘
- 检查某元素是否属于序列的成员,计算序列长度等等
列表定义用[ ],字符串用’ ‘,元组用()
字符串和元组是不可变的,可变的只有列表!

索引

python是从0开始的,然后用负数表示倒数。比如-1表示倒数第一个。

>>> nums = ['a', 2, 3, 4, 5]   # 列表
>>> nums[0]
'a'
>>> nums[-1]                
5

分片

这个就是切切切,当然要制定切的左端和右端,最重要的一点是左闭右开,所以都是用正数表示的切的位置,直接大减小就是切出的序列的长度。

>>> numbers = [1, 2, 3, 4, 5, 6]
>>> numbers[-3:-1]      # 实际取出的是 numbers[-3], numbers[-2]
[4, 5]
>>> numbers[-3:0]       # 左边索引的元素比右边索引出现得晚,返回空序列
[]
>>> numbers = [1, 2, 3, 4, 5, 6, 7, 8]
>>> numbers[-3:]
[6, 7, 8]
>>> numbers[5:]
[6, 7, 8]
# [:]可以复制整个序列

分片的其他知识

  • 使用步长
    left_idx: right_idx: step
    左边比右边小。
    当然仍旧是左闭右开,如果是step为负数,则是从右边往左边取,此时是左边大右边小。
    比如
>>> numbers = [1, 2, 3, 4, 5, 6, 7, 8]
>>> numbers[4:0:-1]       # 取出索引为 4, 3, 2, 1 的元素,仍就是左闭右开。
[5, 4, 3, 2]

这个有啥好说的啊,就是往序列中添加元素呗。直接“+”不就行了。

乘N就是加N次。

>>> [1, 2, 3] * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>>'hehe'*3
'hehehehehehe'

in

检查某个值是否在序列中。

>>>'he' in 'hehh'
True

列表

上面既然已经说了序列的通用操作,那么就说说针对列表有哪些常用的函数吧
- index
- count
- append
- extend
- insert
- pop
- remove
- reverse
- sort

index:就是看某个元素的索引呗。且只返回第一个该元素的索引,稍微想想也知道啊,不可能给你一大堆索引的吧,所以就返回第一个得了。

>>> words = ['hello', 'world', 'you', 'me', 'he','meagain']
>>> words.index('me')
3

count:略吧
append:末尾增加新的元素,由于list的元素类型可以是任意的,所以你可以随便append啊

>>>a = ['a',1,2]
>>>a.append(['what',1])
['a', 1, 2, ['what', 1]]

extend: (⊙v⊙)嗯,扩展,想必也是类似append,但是发现没有,扩展并不是添加,所以它是:
将一个新列表的元素添加到原列表中

>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> a.extend(b)
>>> a
[1, 2, 3, 4, 5, 6]

insert: insert(pos, value) 是将value添加到pos的位置。
pop:默认是移除最后一个,也可以移除指定index的元素。list.pop()或是list.pop(index)
remove:list.remove(‘value’), 只移除第一个匹配的
reverse:反转

显然像这些extend,append,insert, pop, reverse, remove等都是在原序列上进行操作的。
sort是返回新的列表。默认从小到大升序排列。 list.sort(reverse=True)就降序了。
sorted就是在原列表上进行操作
你可能会觉得,啊啊,那我要进行制定方式进行排序呢。加key!

>>> s = ['ccc', 'a', 'bb', 'dddd']
>>> s.sort(key=len)          # 使用 len 作为键函数,根据元素长度排序
>>> s
['a', 'bb', 'ccc', 'dddd']

字符串

显然,满足通用的序列操作。再次强调,只有列表可变啊啊啊!字符串是不可变的。所以不能给字符串赋值。
常用字符串方法
- find
- split
- join
- strip
- replace
- translate
- lower/upper

find: 查找子串呗。没找到就返回-1

>>> motto = "to be or not to be, that is a question"
>>> motto.find('be')            # 返回 'b' 所在的位置,即 3
3
>>> motto.find('be', 4)         # 指定从起始位置开始找,找到的是第 2 个 'be'
16
>>> motto.find('be', 4, 7)      # 指定起始位置和终点位置,没有找到,返回 -1
-1

split: 字符串切成序列
这个有意思啊,相当于字符串往列表转,而且可以指定切的分隔符。
显然默认空格作为分隔符啊

>>> '/user/bin/ssh'.split('/')         # 使用 '/' 作为分隔符
['', 'user', 'bin', 'ssh']
>>> '1+2+3+4+5'.split('+')             # 使用 '+' 作为分隔符
['1', '2', '3', '4', '5']
>>> 'that    is a   question'.split()  # 没有提供分割符,默认使用所有空格作为分隔符
['that', 'is', 'a', 'question']

join: 可以说是split的逆方法吧

>>> '/'.join(['', 'user', 'bin', 'ssh'])
'/user/bin/ssh'
>>>
>>> '+'.join(['1', '2', '3', '4', '5'])
'1+2+3+4+5'
>>> ' '.join(['that', 'is', 'a', 'question'])
'that is a question'
>>> ''.join(['h', 'e', 'll', 'o'])
'hello'

strip:去掉字符串左右两边的空格,或是指定的字符串

>>> '  hello world!   '.strip()                # 移除左右两侧空格
'hello world!'
>>> '%%%   hello world!!!  ####'.strip('%#')   # 移除左右两侧的 '%''#'
'   hello world!!!  '
>>> '%%%   hello world!!!  ####'.strip('%# ')  # 移除左右两侧的 '%''#' 或空格
'hello world!!!'

replace: 替换所有

>>> motto = 'To be or not To be, that is a question'
>>> motto.replace('To', 'to')        # 用 'to' 替换所有的 'To',返回了一个新的字符串
'to be or not to be, that is a question'
>>> motto                            # 原字符串保持不变
'To be or not To be, that is a question'

translate: 看名称就知道了啊,翻译翻译,当然是一个字一个字对应的。所以要用指定的翻译对应表,这开始有点扯了。

>>> from string import maketrans
>>> table = maketrans('aeiou', '12345')
>>> motto = 'to be or not to be, that is a question'
>>> motto.translate(table)
't4 b2 4r n4t t4 b2, th1t 3s 1 q52st34n'
>>> motto
'to be or not to be, that is a question'
>>> motto.translate(table, 'rqu')        # 移除所有的 'r', 'q', 'u'
't4 b2 4 n4t t4 b2, th1t 3s 1 2st34n'

lower/upper: 略

元组

不可变序列,用圆括号表示。

>>> a = (1, 2, 3)    # a 是一个元组
>>> a
(1, 2, 3)
>>> a[0] = 6         # 元组是不可变的,不能对它进行赋值操作
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

一个值的元组

创建一个值的元组需要在值后面再加一个逗号,这个比较特殊,需要牢牢记住:

>>> a = (12,)   # 在值后面再加一个逗号
>>> a
(12,)
>>> type(a)
<type 'tuple'>
>>>
>>> b = (12)    # 只是使用括号括起来,而没有加逗号,不是元组,本质上是 b = 12
>>> b
12
>>> type(b)
<type 'int'>

想想也是啊,因为元组是用圆括号定义的啊,如果只有一个值的话,那么不加逗号不就成为了数了啊。
元组不可变,所以没有append,extend,sort等方法

字典

总说:字典是映射类型,有key和value构成,显然key要求是不可变类型,所以只能是数字,字符串和元组。

字典的三种基本操作

  • 创建字典
    用{ }, 讲完。哈哈,开玩笑的。
>>> d1 = {'name': 'ethan', 'age': 20}
>>> d1
{'age': 20, 'name': 'ethan'}
>>> d1['age'] = 21          # 更新字典
>>> d1
  • 基本遍历
    for key in dict 结构
for key in d:
    print '%s: %s' % (key,d[key])

另一种遍历,如果遍历时要删除字典的某一项,那么要改改遍历方法:

for key in d.keys():  # python3的时候改成list(d.keys())
    if key == 'name'
        del d[key]
for k,v in d.iteritems():
    print '%s: %s' % (k,v)
  • 判断键是否在字典
    一样的啊,用in呗。

字典的常用方法

  • clear
  • copy
  • get
  • setdefault
  • update
  • pop
  • popitem
  • keys/iterkeys
  • values/iteritems
  • fromkeys

clear:

>>> d1 = {}
>>> d2 = d1
>>> d2['name'] = 'ethan'
>>> d1
{'name': 'ethan'}
>>> d2
{'name': 'ethan'}
>>> d1.clear()      # d1 清空之后,d2 也为空
>>> d1
{}
>>> d2
{}

copy

copy: 这个比较特殊诡异。竟然是浅复制。。
copy 方法实现的是浅复制(shallow copy)。它具有以下特点:

  • 对可变对象的修改保持同步;
  • 对不可变对象的修改保持独立 ;
# name 的值是不可变对象,books 的值是可变对象,再读一遍,是看“值”是什么类型!!
>>> d1 = {'name': 'ethan', 'books': ['book1', 'book2', 'book3']}
>>> d2 = d1.copy()
>>> d2['name'] = 'peter'         # d2 对不可变对象的修改不会改变 d1
>>> d2
{'books': ['book1', 'book2', 'book3'], 'name': 'peter'}
>>> d1
{'books': ['book1', 'book2', 'book3'], 'name': 'ethan'}
>>> d2['books'].remove('book2')  # d2 对可变对象的修改会影响 d1
>>> d2
{'books': ['book1', 'book3'], 'name': 'peter'}
>>> d1
{'books': ['book1', 'book3'], 'name': 'ethan'}
>>> d1['books'].remove('book3')  # d1 对可变对象的修改会影响 d2
>>> d1
{'books': ['book1'], 'name': 'ethan'}
>>> d2
{'books': ['book1'], 'name': 'peter'}

深复制就用copy模块的deepcopy。

get

get: 就是防止你随便访问不存在的项产生KeyError。用get就返回空

>>> d = {}
>>> d['name']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'name'
>>> print d.get('name')
None

setdefault

setdefault:就是设定一个默认的键值对,如果原字典已经设置了,那么就不会采用默认的键值对,如果原子典没有,那么显然会添上默认的键值对。

>>> d = {}
>>> d.setdefault('name', 'ethan')   # 返回设定的默认值 'ethan'
'ethan'
>>> d                               # d 被更新
{'name': 'ethan'}
>>> d['age'] = 20
>>> d
{'age': 20, 'name': 'ethan'}
>>> d.setdefault('age', 18)         # age 已存在,返回已有的值,不会更新字典
20
>>> d
{'age': 20, 'name': 'ethan'}

update

update: 将一个字典添加到原字典,如果存在相同的键则会进行覆盖。

items/iteritems

items 方法将所有的字典项以列表形式返回,这些列表项的每一项都来自于(键,值)。我们也经常使用这个方法来对字典进行遍历。
iteritems 的作用大致相同,但会返回一个迭代器对象而不是列表,同样,我们也可以使用这个方法来对字典进行遍历,而且这也是推荐的做法.
推荐的做法在前面已经阐述。

keys/iterkeys 与values/itervalues

keys 方法将字典的键以列表形式返回,iterkeys 则返回针对键的迭代器。
values 方法将字典的值以列表形式返回,itervalues 则返回针对值的迭代器。

pop

移除字典中某个键值对,并返回给定的键的值
popitem随机移除某个键值对

元素为字典的列表 排序

就是说一个列表中有很多个字典,然后你要对这些字典进行排序。

students = [
    {'name': 'john', 'score': 'B', 'age': 15},
    {'name': 'jane', 'score': 'A', 'age': 12},
    {'name': 'dave', 'score': 'B', 'age': 10},
    {'name': 'ethan', 'score': 'C', 'age': 20},
    {'name': 'peter', 'score': 'B', 'age': 20},
    {'name': 'mike', 'score': 'C', 'age': 16}
]
  • 按score从小到大排序
>>> sorted(students, key=lambda stu: stu['score'])
#返回的字典的键值对先后顺序与下面不一样。然而并没有什么关系,为了简便,不改了。
[{'age': 12, 'name': 'jane', 'score': 'A'},
 {'age': 15, 'name': 'john', 'score': 'B'},
 {'age': 10, 'name': 'dave', 'score': 'B'},
 {'age': 20, 'name': 'peter', 'score': 'B'},
 {'age': 20, 'name': 'ethan', 'score': 'C'},
 {'age': 16, 'name': 'mike', 'score': 'C'}]
  • 按 score 从大到小排序
>>> sorted(students, key=lambda stu: stu['score'], reverse=True)  # reverse 参数
  • 按 score 从小到大,再按 age 从小到大
sorted(students, key=lambda stu: (stu['score'], stu['age']))
  • 按 score 从小到大,再按 age 从大到小
sorted(students, key=lambda stu: (stu['score'], -stu['age']))

集合

一句话,集合也用{ }, 它是一组key的集合,没有value。特性就是key不能重复!

>>> se = {'a',1}
>>> se
set(['a', 1])
  • 遍历
    仍旧是for e in s: 结构呗
  • 添加
    add() 方法
>>> s = {'a', 'b', 'c', 'a', 'd', 'b'}
>>> s.add('e')  #没效果
>>> s
set(['a', 'c', 'b', 'e', 'd'])
>>> s.add(4)
>>> s
set(['a', 'c', 'b', 4, 'd', 'e'])
  • 删除
    remove()
  • 子集判断
    set.issubset(subset)

交/并/差

分别是 & | -

>>> s1 = {1, 2, 3, 4, 5, 6}
>>> s2 = {3, 6, 9, 10, 12}
>>> s3 = {2, 3, 4}
>>> s1 & s2            # 交集
set([3, 6])
>>> s1 | s2            # 并集
set([1, 2, 3, 4, 5, 6, 9, 10, 12])
>>> s1 - s2            # 差集
set([1, 2, 4, 5])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值