-
元组:固定长度,不可变的Python对象序列。
tup = 4,5,6 //创建元组最简单的办法
可以通过
tuple
函数将任意序列或迭代器转换为元组。tuple([4,0,2]) // (4,0,2) tuple('string') // ('s','t','r','i','n','g')
如果元组中的一个对象是可变的,例如列表,则你可以在它内部进行修改。
可以使用
+
连接元组,生成更长的元组。将元组乘以整数,可以生成含有多份拷贝的元组。
-
元组拆包
如果你想将元组类型的表达式赋给变量,则Python会对等号右边的元组进行拆包。tup = 4,5,6 a,b,c = tup // a = 4,b = 5, c = 6 tup = 4,5,(6,7) a,b,(c,d) = tup // a = 4,b = 5,c = 6, d = 7
一个常用的场景:遍历元组或列表组成的序列。
seq = [(1,2,3),(4,5,6),(7,8,9)] for a,b,c in seq: print(a,b,c) # 1 2 3 4 5 6 7 8 9
一个更高级的拆包方法:
*
val = 1,2,3,4,5 a,b,*rest = val // a = 1,b = 2,rest = (3,4,5)
-
元组方法
由于元组内容和长度无法改变,所以实例方法很少,一个常见的方法count
,计算某个数值在元组中出现的次数。a = (1,2,3,1,1) a.count(1) // 3
-
-
列表:长度可变,内容可修改。
list
函数,在数据处理中常用于将迭代器或者生成器转化为列表。gen = range(10) //生成一个range(0,10)的对象 list(gen) // [0,1,2,3,4,5,6,7,8,9]
增加和移除元素
append
:将元素添加到列表尾部。
insert
:将元素插入到指定位置。
pop
:将特定位置的元素移除并返回。
remove
:定位第一个符合要求的值并移除。
in
:检查一个值是否在列表中。-
连接和联合列表
- 可以使用
+
号连接。 - 如果有一个已经定义的列表,可以使用
extend
添加多个元素。
请注意:通过添加内容来连接列表是一种相对高代价的操作,因为连接过程中创建了新列表,并且还要复制对象,使用extend
将元素添加到已经存在的列表中是更好的方式,尤其是在需要构建一个大型列表时。
上述实现比下述更快。everything = [] for chunk in list_of_lists: everything.extend(chunk)
everything = [] for chunk in list_of_lists: everything = everything + chunk
- 可以使用
-
排序
sort
方法:列表内部进行排序(无需新建一个对象)。
bisect
模块:实现了二分搜索和已排序列表的插值。import bisect c = [1,2,2,2,3,4,7] bisect.bisect(c,2) // 返回 4,表示2应该插入列表c中第4个位置。 bisect.insort(c,6) // c = [1,2,2,2,3,4,6,7]
-
切片
将序列赋值给变量:seq = [1,2,3,4] seq[4:5] = [5,6] // seq [1,2,3,4,5,6]
步进值可以在第二个冒号后面使用,当需要对列表或元组进行翻转时,可以向步进传值-1。
-
内建序列函数
enumerate
:遍历一个序列会同时返回当前元素的索引。
用法:for i,value in enumerate(collection):
-
sorted
:函数返回一个根据任意序列中的元素新建的已排序列表。sorted([7,1,2,6,0,3,2]) // [0,1,2,2,3,6,7] 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')]
zip
可以处理任意长度的序列,生成列表的长度由最短的序列决定。seq3 = [False,True] list(zipped(seq1,seq2,seq3)) # [('foo','one',False),('bar','two','True)]
常用的场景:同时遍历多个序列,有时候会和
enumerate
同时使用: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
给定一个已经配对的序列时,
zip
函数可以将其拆分。pitchers = [('Nolan','Ryan'),('Roger','Clemens'),('Schilling','Curt')] firstname,lastname = zip(*pitchers) #firstname:('Nolan', 'Roger', 'Schilling') #lastname:('Ryan', 'Clemens', 'Curt')
reversed
:将序列元素倒序排列。
-
字典:也称为哈希表,键值对方式存在。
d1 = {} #创建字典 d[1] = 'some value' # 向d中添加键值对 1 in d #检查d中是否存在键 1
del
:按键删除值。
pop
:按键删除值并返回。
keys()
:返回字典中的键。
value()
:返回字典中的值。
update
:将两个字典合并。d1 = {1:2} d2 = {3:4} d1.update(d2) # d1 = {1:2,3:4}
-
默认值
通常情况下,会有这样的代码逻辑,如果键key存在于字典中,那么令value等于它的值,否则令value等于其他值。if key in dict: value = dict[key] else: value = default_value
上述代码可以简写为:
value = dict.get(key,default_value)
,如果不写参数default_value,key不存在时会返回None。 -
setdefault
可以用来设定字典默认值。
dict.setdefault(key,value)
- 一个例子:根据首字母分类为包含列表的字典。
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)
setdefault
方法就是为了这个目的而产生的,可以将上述代码写为:for word in words: letter = word[0] by_letter.setdefault(letter,[]).append(word)
- 一个例子:根据首字母分类为包含列表的字典。
-
-
集合
可以理解为只含有键的字典。issubset
:检查一个集合是否是另一个集合的子集。
例:{1,2,3}.issubset{1,2,3,4,5}
当两个集合内的内容一模一样时,两个集合才相等。
{1,2,3} == {3,2,1}
-
列表、集合和字典的推导式
列表推导式是最受欢迎的Python语言特性之一!
基本形式:[expr for val in collection if condition]
,其中if condition
过滤条件可以忽略/
与下面for循环等价:result = [] for val in collection: if condition: result.append(expr)
字典和集合推导式是列表推导式的拓展:
dict = {key-expr:value:expr for value in collection if condition}
set = {expr for value in collection if condition}
假设我们想要一个集合,集合里包含列表中字符串的长度,我们可以通过集合推导式实现:
unique_length = {len(x) for x in strings}
也可以使用map
函数更函数化,更简洁的表达:
set(map(len,string))
-
嵌套列表推导式
假设有一个包含列表的列表:all_data = [['John','Emily','Michael','Mary','Steven'],['Maria','Juan','Javier','Natalia','Pilar']]
我们想要一个列表包含所有含有2个以上字母'e'的名字,for循环写法如下:
names_of_interest = [] for names in all_data: enough_es = [name for name in names if name.count('e') >= 2] names_of_interest.extend(enough_es)
实际上更简洁的写法如下,用嵌套列表推导式:
result = [ name for names in all_data for name in names if name.count('e') >= 2]
lambda
函数
例:lambda x,y:x+y
,返回的是一个函数对象,返回x+y
的值。
因为没有__name__
属性,所以叫做匿名函数。-
柯里化
现在我们有一个函数如下:def add_nums(x,y): return x+y
使用这个函数衍生出一个新的函数:
add_five = lambda y:add_nums(5,y)
上述过程就叫做柯里化。 -
生成器
创建一个生成器,只需要将函数返回关键字return
改为yield
。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 = squares() // gen : <generator object squares at 0x11ea93a98> 显示是一个生成器 for x in gen: print(x) // Generating square from 1 to 100 1 4 9 16 25 36 49 64 81 100
由上述可见,
for
循环后面可以跟一个生成器generator
或者迭代器iterator
,用来每次向循环中返回一个对象。- 生成器表达式
gen = ( x ** 2 for x in range(100))
上述表达式与下面代码是等价的:
很多情况下生成器表达式作为函数参数用于替代列表表达式:def _make_gen(): for x in range(100): yield x ** 2
sum(x ** 2 for x in range(100)) #328350 dict((i,i ** 2) for i in range(5)) # {0:0,1:1,2:4,3:9,4:16,5:25}
- 生成器表达式
-
文件与操作系统
打开文件进行读取或写入,使用内建函数open
和绝对、相对路径。
f = open(path)
默认情况下文件是以只读模式r
打开的。之后我们可以像处理列表一样处理文件中的内容。
当你使用open
来创建文件对象时,结束操作后一定要显式的关闭文件。
f.close()
另一种更简单的方式:
with open(path) as f:
,文件会在with
代码块后自动关闭。- 一些操作句柄的方法:
f.read()
:读取()个字符。
f.tell()
:给出当前句柄的位置。
f.seek()
:将句柄位置跳转到指定字节。
- 一些操作句柄的方法:
第3章 内建数据结构、函数及文件
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...