文章目录
数据结构和序列
在 Python中,序列类型包括字符串、列表、元组、集合和字典,这些序列支持以下几种通用的操作,但比较特殊的是,集合和字典不支持索引、切片、相加和相乘操作。
序列索引:
序列中,每个元素都有属于自己的编号(索引)。从起始元素开始,索引值从 0 开始递增。
除此之外,Python 还支持索引值是负数,此类索引是从右向左计数,换句话说,从最后一个元素开始计数,从索引值 -1 开始。
序列切片:
通过切片操作,可以选取一个序列的子集,生成一个新的序列。
格式如下:
sname[start : end : step]
其中,各个参数的含义分别是:
- sname:表示序列的名称;
- start:表示切片的开始索引位置(包括该位置),此参数也可以不指定,会默认为 0,也就是从序列的开头进行切片;
- end:表示切片的结束索引位置(不包括该位置),如果不指定,则默认为序列的长度;
- step:表示在切片过程中,隔几个存储位置(包含当前位置)取一次元素,也就是说,如果 step 的值大于 1,则在进行切片去序列元素时,会“跳跃式”的取元素。如果省略设置 step 的值,则最后一个冒号就可以省略。
序列相加:
Python 中,支持两种类型相同的序列使用“+”运算符做相加操作,它会将两个序列进行连接,但不会去除重复的元素。连接后的是一个新的序列。
这里所说的“类型相同”,指的是“+”运算符的两侧序列要么都是列表类型,要么都是元组类型,要么都是字符串。
序列相乘:
Python 中,使用数字 n 乘以一个序列会生成新的序列,其内容为原来序列被重复 n 次的结果。
检查元素是否包含在序列中:
Python 中,可以使用 in 关键字检查某元素是否为序列的成员,其语法格式为:
value in sequence
其中,value 表示要检查的元素,sequence 表示指定的序列。
和 in 关键字用法相同,但功能恰好相反的,还有 not in 关键字,它用来检查某个元素是否不包含在指定的序列中.
元组tuple
-
固定长度,不可变。
不可变的含义是元组各个位置上的对象是无法修改的,如果某个对象本身是可修改的,是可以对该对象进行修改的(只是不能将该对象换成其他对象) -
表示形式:
#定义:圆括号 tup=4,5,6 tup=((4,5),(6,7)) #定位元素:从0开始 tup[0] #将任意序列或迭代器转化为元组 tuple([4,0,2]) tup=tuple('string')
拆包
#基础用法
tup=4,5,(6,7)
a,b,(c,d)=tup
#abcd值已得到
#应用1:交换
a,b=1,2
a,b=b,a
#应用2:遍历元组或列表组成的序列
seq=[(1,2,3),(4,5,6),(7,8,9)]
for a,b,c in seq
print('a={0},b={1},c={2}'.format(a,b,c))
#拓展:*rest
values=1,2,3,4,5
a,b,*_=values
#_=3,4,5
方法
count
a=1,2,2,3,2,4
a.count(2)
#out:4
列表list
-
长度可变,内容可以修改
-
表示形式
#定义:中括号 a_list=[2,3,4] #将元组或迭代器或生成器转化为列表 b_list=list(range(10))
增删
元素
#增
#append:尾部增加
b_list.append('d')
#insert:指定位置增加
b_list.insert(1,'red')
#删
#pop:insert的反操作,指定位置删除
b_list.pop(2)
#remove:定位第一个符合要求的值并移除
b_list.remove('red')
列表
#方法1:+号
#创建新列表,代价高
[4,None,'foo']+[2,3,4]
#方法2:extend
#在原列表的基础上添加,代价低
x=[4,None,'foo']
x.extend([2,3,4])
检查元素
'red' in b_list
#out:True
'djiao' not in b_list
#out:False
排序
sort
#关键选项:key,用于生成排序值
a.sort(key=len)
#含义:通过字符串长度进行排序
内建序列函数里也有一个排序函数sorted,和sort的区别是,sorted会产生一个新的排好序的列表。
内建序列函数
enumerate
遍历一个序列的同时追踪当前元素的索引。
#应用:构造一个字典,序列值为字典的索引值
some_list = ['foo', 'bar', 'baz']
mapping = {}
for i, v in enumerate(some_list):#索引,值
mapping[v] = i
#mapping={'foo': 0, 'bar': 1, 'baz': 2}
sorted
新建一已排序列表。
sorted([7, 1, 2, 6, 0, 3, 2])
sorted('horse race')
#[' ', 'a', 'c', 'e', 'e', 'h', 'o', 'r', 'r', 's']
zip
将列表、元组或其他序列的元素配对,新建一个元组构成的列表。
seq1 = ['foo', 'bar', 'baz']
seq2 = ['one', 'two', 'three']
zipped = zip(seq1, seq2)
list(zipped)
#[('foo', 'one'), ('bar', 'two'), ('baz', 'three')]
type(zipped)
#zip
生成列表长度有最短的序列决定。
seq3 = [False, True]
list(zip(seq1, seq2, seq3))
#[('foo', 'one', False), ('bar', 'two', True)]
#应用1:遍历多个序列
for i, (a, b) in enumerate(zip(seq1, seq2)):
print('{0}: {1}, {2}'.format(i, a, b))
#0: foo, one
#1: bar, two
#2: baz, three
#应用2:拆分序列
pitchers = [('Nolan', 'Ryan'), ('Roger', 'Clemens'),
('Curt', 'Schilling')]
first_names, last_names = zip(*pitchers)
print(first_names)
print(last_names)
#('Nolan', 'Roger', 'Curt')
#('Ryan', 'Clemens', 'Schilling')
reversed
倒序排列。结果是生成器。
list(reversed(range(10)))
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
字典dict
拥有灵活尺寸的键值对集合,键和值都是python对象。
值可以是任何python对象,键必须是不可变对象(标量、元组且元组内对象也不可变)
可通过hash函数检查对象是否可变
#定义
empty_dict = {}
d1 = {'a' : 'some value', 'b' : [1, 2, 3, 4]}
#访问
d1[7] = 'an integer'
d1['b']
#检查是否有某个--键--
'b' in d1
#删除某键值对
#del关键字
del d1[5]#键为5
#pop函数:返回被删除的值
ret = d1.pop('dummy')
#键值迭代器
list(d1.keys())
list(d1.values())
#['a', 'b']
#['some value', [1, 2, 3, 4]]
#update函数合并字典:对于原字典已存在的键,如果传给update的数据也含有相同的键,则它的值将会被覆盖。
#{'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer'}
d1.update({'b' : 'foo', 'c' : 12})
#{'a': 'some value', 'b': 'foo', 7: 'an integer', 'c': 12}
从序列生成字典
#方法1
mapping = {}
for key, value in zip(key_list, value_list):
mapping[key] = value
#方法2
mapping = dict(zip(range(5), reversed(range(5))))
默认值
#get、pop函数
value = some_dict.get(key, default_value)
#带默认值的get方法会在key不是字典的键时返回默认值
#实现下列代码的简单方式:
words = ['apple', 'bat', 'bar', 'atom', 'book']
by_letter = {}
for word in words:
letter = word[0]
if letter not in by_letter:
by_letter[letter] = [word]
else:
by_letter[letter].append(word)
#方式1
for word in words:
letter = word[0]
by_letter.setdefault(letter, []).append(word)
#方式2
from collections import defaultdict
by_letter = defaultdict(list)
for word in words:
by_letter[word[0]].append(word)
集合set
无序且元素唯一的容器。
集合元素不可变。
构造方法:
集合操作具体看P68.
列表推导式
过滤一个容器的元素,用一种简明的表达式转换传递给过滤器的元素,从而生成一个新的列表。
#列表推导式
[expr for val in collection if condition]
#字典推导式
{key-expr:value-expr for value in collection if condition}
#集合推导式
{expr for val in colletion if condition}
strings = ['a', 'as', 'bat', 'car', 'dove', 'python']
[x.upper() for x in strings if len(x) > 2]
#['BAT', 'CAR', 'DOVE', 'PYTHON']
unique_lengths = {len(x) for x in strings}
#{1, 2, 3, 4, 6}
#这样写更简单 set(map(len, strings))
#实现字符串与其位置相匹配
loc_mapping = {val : index for index, val in enumerate(strings)}
#{'a': 0, 'as': 1, 'bat': 2, 'car': 3, 'dove': 4, 'python': 5}
#嵌套列表推导式:for循环部分是根据嵌套的顺序排列的
result = [name for names in all_data for name in names
if name.count('e') >= 2]
#注意和列表推导式区分:
[[x for x in tup] for tup in some_tuples]
#[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
函数
#定义
def my_function(x, y, z=1.5):
if z > 1:
return z * (x + y)
else:
return z / (x + y)
#参数的分类:位置参数和关键字参数,关键字参数用于指定默认值。关键字参数必须在位置参数后。
my_function(5, 6, z=0.7)
my_function(3.14, 7, 3.5)
my_function(10, 20)
#全局变量
a = None
def bind_a_variable():
global a
a = []
#返回多个值
def f():
a = 5
b = 6
c = 7
return a, b, c
#函数是对象,可以作为参数传递
#应用1:清洗数据
states = [' Alabama ', 'Georgia!', 'Georgia', 'georgia', 'FlOrIda',
'south carolina##', 'West virginia?']
#原方法
import re
def clean_strings(strings):
result = []
for value in strings:
value = value.strip()
value = re.sub('[!#?]', '', value)
value = value.title()
result.append(value)
return result
#新方法
clean_ops = [str.strip, remove_punctuation, str.title]
def clean_strings(strings, ops):
result = []
for value in strings:
for function in ops:
value = function(value)
result.append(value)
return result
#应用2
def remove_punctuation(value):
return re.sub('[!#?]', '', value)
for x in map(remove_punctuation, states):#map函数:将一个函数运用到一个序列上
print(x)
匿名函数
strings = ['foo', 'card', 'bar', 'aaaa', 'abab']
strings.sort(key=lambda x: len(set(list(x))))
#['aaaa', 'foo', 'abab', 'bar', 'card']
生成器
#生成方式
#函数返回生成器
def squares(n=10):
print('Generating squares from 1 to {0}'.format(n ** 2))
for i in range(1, n + 1):
yield i ** 2
#生成器表达式:将列表表达式的括号改为小括号
gen = (x ** 2 for x in range(100))
实际调用生成器时,代码并不会立即执行,直到你请求生成器的元素时,才会执行它的代码。
itertools模块有许多生成器相关函数,见P78
错误和异常处理
#完整格式
f=open(path,'w')
try:
write_to_file(f)
except:#try失败执行
print("failed")
else:#try成功执行
print("succeeded")
finally:#无论try是否成功都执行
f.close();
#捕捉特定异常
def attempt_float(x):
try:
return float(x)
except (TypeError, ValueError):
return x
文件与操作系统
开关文件:
f=open(path)
#关闭方法1
f.close()
#关闭方法2:with as 文件在with代码块结束后自动关闭。
with open(path) as f:
lines = [x.rstrip() for x in f]