Python语法基础

1. 元组tuple

元组 :长度固定,元素不可变,赋值会报错
(如果元素是可变的,则可修改该元素)

nested_tup = (4,5,6),(7,8)  # 嵌套元组
nested_tup   # ((4, 5, 6), (7, 8))

tup = tuple('string')  # 序列类型转换为元组
tup
tup[0]  # 通过下标访问里面元素

tup = (1,2,3)+(4,5)  # 加号连接元组为一个元组
tup = tup*4          # 乘号复制元组的值为一个元组

拆包: 多个值赋给多个值,python会自动识别

a, b, c = (4,5,6)   # 多个值可以为一个元组中的多个元素
b
a, b, (c, d) = 4,5,(6,7)
d

# 通过拆包交换变量名
a, b = b, a

# 通过拆包遍历序列
seq = [(1,2,3),(4,5,6),(7,8,9)]
for a,b,c in seq:          # 对每个元素进行拆包,相当于两重循环
    print('a={},b={},c={}'.format(a,b,c))
    
# 通过拆包从函数返回多个值

# 高级拆包:*rest:不是一一对应关系了,在获得我们指定位置想要的元素之后,对于剩余的其他所有元素统统放入rest变量中,
# rest只是名字,可以是*任何名字,对于不想要的变量,可以用_表示
values = 1,2,3,4,5
a,*rest,b= values   # a=1,b=5,rest=[2,3,4]

元组的方法:count:计数,某个值在元组中出现的次数

a = 1,1,2,2,2,3
a.count(2)      # 3次
2.列表list

可修改,使用[]创建列表或list将别的序列或迭代器(例如range)转换为列表

l = [1,2,3]   # []创建列表
l=[]          # 创建空列表

tup = (4,5,6)  
b = list(tup)  # 将别的序列转换为列表
b[1] = 1  # 修改元素的值:直接赋值
b         # [4,1,6]

1.向列表中添加元素

## 列表尾部追加元素:.append()
l.append('a')
## 在任意位置插入元素:.insert(位置,元素),代价较高
l.insert(1,'b')

2.移除列表中的元素

## 通过索引移除指定位置的元素:.pop(索引)
l.pop(2)
## 通过值直接移除元素,只移除第一个找到的元素:.remove()
l.remove('a')

3.检查列表是否包含某个元素:in,not in,返回True or False,原理是线性逐个扫描

'a' in l
'a' not in l

4.连接列表:
+:返回一个新列表,代价较高
.extend(list): 将新元素的列表添加到已存在的列表,相当于扩展,推荐

list_of_lists = [[1,2,3],['a','b']]
l = []
for chunk in list_of_lists:  # 对于包含许多小列表的大列表
    l.extend(chunk)           # 依次连接这些小列表
l      # [1, 2, 3, 'a', 'b']

5.排序:
.sort():列表自带的排序方法,将列表直接更新

l.sort()
l
# 参数key=函数名:函数生成排序值,根据这个排序
# 参数reverse=True/False,默认升序False
l = ['a','aaa','aa']
l.sort(key=len,reverse=True)  # 按照元素长度降序排序
l   # ['aaa', 'aa', 'a']

对于已排好序的列表,使用bisect模块,实现二分搜索和插值

import bisect
l=[1,2,3,4,7]       # 已排序列表
bisect.bisect(l,5)  # 在l中找出5应该被插入的位置
bisect.insort(l,5)  # 向l中插入5
l                   # [1, 2, 3, 4, 5, 7]
3. 切片

对序列按索引取子集,区间是[start,end),不包含end,元素个数是end-start。
省略start或end则默认从开头或到结尾,包括开头和结尾。
可以使用负索引
可以带步长:seq[start: end: step],步长为-1时,将序列逆序。

l = [7,2,3,7,5,6,0,1]
l[1:5]          # [2, 3, 7, 5]
l[3:5] = [6,3]  # 将位置3,4的元素7,5替换为6,3
l[3:4] = [6,3]  # 将位置3的元素6替换为6,3, l is [7, 2, 3, 6, 3, 3, 6, 0, 1]
l[3:]           # 从位置3的元素到最后一个
l[-4:]          # 从位置-4的元素到最后一个,搜索方向都是正向,只不过两套索引,[3, 6, 0, 1]
l[::2]          # 每隔一个取一个值  [7, 3, 3, 6, 1]
l[::-1]         # 列表倒序,[1, 0, 6, 3, 3, 6, 3, 2, 7]
4. 常用序列函数
enumerate()

遍历序列的同时带上索引

for i,value in enumerate(seq):
    # do something using i or value
sorted()

对任意序列排序,返回新的列表,参数同key,reverse

s = 'apple'
s1 = sorted(s,reverse=True)  # 对字符串的字符序列降序排列
s1   # ['p', 'p', 'l', 'e', 'a']
zip()

拉链,将多个序列按元素挨个配对,生成由配对元组构成的zip对象
序列长度不同时,最终长度由最短的序列决定

seq1 = [1,2,3]
seq2 = ['a','b','c']
zipped = zip(seq1,seq2)
list(zipped)       # [(1, 'a'), (2, 'b'), (3, 'c')]

解开配对,使用value1,…=zip(*配对对象)

value1,value2 = zip(*zipped)  
value2    # ('a', 'b', 'c')

常用场景:同时遍历多个序列

for i,(a,b) in enumerate(zip(seq1,seq2)):   # zip配对后是配对元组
    print('{0}:{1},{2}'.format(i,a,b))

在这里插入图片描述

reversed()

将序列元素倒序,是一个生成器,需要用list()或for循环对其实例化才能看见里面的内容。

list(reversed(range(10)))  # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
5. 字典

也叫哈希表或关联数组,是键值对集合,使用大括号{}创建字典,用逗号分隔键值对。
字典中没有位置索引,key就是索引

empty_d={}    # 建立空字典
d = {'a':'some value','b':[1,2,3]}  # 值可以是任何类型
d['c'] = 8    # 通过key插入新元素
d['c']        # 通过key访问元素
'b' in d      # 检查某个键是否在字典中
  1. 删除元素,key与value是绑定的
    .pop(key) :返回对应的值,并从字典中移除
    del d[key] :直接删除
# .pop(key)返回对应的值,并从字典中移除
ret=d.pop('c')  # d is {'a': 'some value', 'b': [1, 2, 3]}

# del d[key]:直接删除
d[1] = '1'  # 增加一个元素1:'1' # 注意,加引号是字符串,这里的key是整数1
del d[1]    # 字典中没有位置索引,key就是索引
  1. 输出键的列表,值的列表
# 可以用list()更清楚的表示格式
d.keys()
list(d.values())
  1. 合并两个字典,键相同的元素将被覆盖,相当于扩展
d1 = {'a':'some value','b':[1,2,3]}
d2 = {'b':'foo','c':8}
d1.update(d2)
d1        # {'a': 'some value', 'b': 'foo', 'c': 8}
  1. 由于字典本质是含有两个元素的元组(2-元组)的集合,因此2-元组的列表可以转换成字典。
# 配对后的序列变成字典
mapping = dict(zip(range(5),reversed(range(5))))
mapping  # {0: 4, 1: 3, 2: 2, 3: 1, 4: 0}
  1. 默认值
    常见场景:将字典的值聚集成另一种值集合
    比如,将单词按照首字母归类,一类是一个列表
    普通做法:
words = ['apple','bat','bar','atom','book']
d = {}
for word in words:
    initial = word[0]  # 取出首字母
    if initial not in d:  # 如果字典中没有该首字母,
        d[initial] = [word]  # 则新建一个元素,值是列表
    else:
        d[initial].append(word)  # 如果有该首字母,则把该单词直接追加到值列表
d  # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}

.setdefault(key, default=None)方法:Insert key with a value of default if key is not in the dictionary.
当key不存在时,插入一个带默认值的key,返回该key的值,当key存在时,返回该key对应的值。

# 若key不存在,添加该元素,使用默认值
d={'a':1}
d.setdefault('b',2) # 2,d is {'a': 1, 'b': 2}

# 若key已存在,则忽略默认值,返回该key的值
d={'a':1,'b':0}
d.setdefault('b',2) # 0, d is {'a': 1, 'b': 0}
d

所以上述任务的简单做法是:

words = ['apple','bat','bar','atom','book']
d = {}
for word in words:
    initial = word[0]  # 取出首字母
    d.setdefault(initial,[]).append(word)  # 设置默认值是空列表

更简单的做法是使用内建的集合模块collections中的defaultdict类

from collections import defaultdict

d = defaultdict(list)  # 生成一个字典,所有键的默认值都是空列表
for word in words:
    d[word[0]].append(word)  # 按照索引word[0]返回值,空列表或非空列表

defaultdict()方法:
普通的字典用法一般是dict={},添加元素dict[key] =value,调用的时候dict[key] = xxx,但前提是key在字典里,如果不在字典里就会报错。
这时defaultdict就能派上用场了,defaultdict的作用是在于,当字典里的key不存在但被查找时,返回的不是keyError而是一个默认值。
defaultdict接受一个工厂函数作为参数,如下来构造:
dict =defaultdict(factory_function)
factory_function可以是list、set、str等等,作用是当key不存在时,返回的是工厂函数的默认值,比如list对应[ ],str对应的是空字符串,set对应set( ),int对应0。
相当于向字典中传入类型,默认值使用该类型的默认值,以避免出现键不在字典中的报错。

dict1 = defaultdict(int)
dict2 = defaultdict(set)
dict3 = defaultdict(str)
dict4 = defaultdict(list)
dict1[2] ='two'

print(dict1[1])
print(dict2[1])
print(dict3[1])
print(dict4[1])
print(dict1[2])

在这里插入图片描述
中间是空串的显示。
6. key的类型
value可以是任何类型,但key必须是不可变的对象,(比如元组中的对象也必须不可变)。可以通过哈希化检测,一个对象若能哈希化,则可以作为字典的键。
hash()

hash('string')  # -6847109138761192205
hash((1,2,(2,3))) # 1097636502276347782
hash((1,2,[2,3]))  # TypeError: unhashable type: 'list'

列表转换为元组则可以作为key.(tuple())

d = {}
d[tuple([1,2,3])] = 5
d   # {(1, 2, 3): 5}
6. 集合set

无序,唯一
set():变成集合
{}: 创建集合

a = {2,2,2,1,3,4} # 创建集合,a is {1,2,3,4}
b = {3,5,6,7}
a | b       # 集合求并集
a & b       # 交集
# 增强运算
c = a.copy()
c |= b    # c = c|b
c      # {1, 2, 3, 4, 5, 6, 7}

{1,2,3} == {3,2,1}  # True

常用函数:
在这里插入图片描述

7. 推导式

1.列表推导式:result = [expr for val in collection if condition]
等价于

result = []
for val in collention:
    if condition:   # 过滤条件
        result.append(expr)

expr是计算结果,顺序是先做for循环,再判断,最后得到结果

## 过滤出字符大于2的单词并大写显示
strings = ['a','as','apple']
l = [x.upper() for x in strings if len(x)>2]
l   # ['APPLE']

2.集合推导式:result = {expr for val in collection if condition}

## 得到字符串列表中字符串的长度集合
s = {len(x) for x in strings}
s  # {1, 2, 5}

方法二:使用map函数,更简洁
map(function,iterable,…):对可迭代对象iterable中的每一个元素调用 function 函数,返回map对象。可以是自定义函数。

list(map(len,strings))  # [1, 2, 5]
set(map(len,strings))   # {1, 2, 5}

map,不止能传入一个可迭代对象做为参数。也可以传入多个。

ls1='ABC'
ls2='abc'
print(list(map(lambda x,y:x+y,ls1,ls2)))  
# ['Aa', 'Bb', 'Cc']

3.字典推导式:result = {key_expr:value_expr for val in collection if condition}
4.嵌套列表推导式
对应于两重循环,for的顺序与嵌套for循环的顺序一致,由于可读性,一般不超过两重.
在这里插入图片描述

# 获得含有两个e以上的名字的列表
all_data = [['John','Steven'],['Juan','Pilar']]
l = [name for names in all_data for name in names if name.count('e') >= 2]  # 对于每个小列表中的每个名字,如果e计数>=2,返回这个名字
l   # ['Steven']
# 将含元组的列表扁平化为一个简单的列表
a = [(1,2,3),(4,5,6),(7,8,9)]   # 只要能构成两重循环即可,不一定非是两重列表
l = [x for tup in a for x in tup]  # 相对于嵌套循环里的append,推导式自动扩展列表
l  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

列表推导式中的列表推导式
最终结果是嵌套列表

a = [(1,2,3),(4,5,6),(7,8,9)]
l = [[x for x in tup] for tup in a]   # 挨个返回的是列表,最终结果是嵌套列表
l    # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
8.函数

def关键字声明是一个函数,return关键字返回值,遇到return即停止不再向下执行
def 函数名(参数表列):
  函数体
  return 返回值

  • 参数包括:
    普通参数(即位置参数);
    关键字参数(定义时指定默认值(成为可选参数)的参数)。
    关键字参数必须在位置参数后面。
    所有参数都有参数名,调用时如果指明参数名则位置参数之间顺序任意,关键字参数之间顺序任意。
  • 函数内变量的作用域:默认局部,函数执行完成时销毁。global关键字声明为全局变量
  • 返回多个值
     return a,b,c
    a,b,c = f()

    实质是返回了一个元组,元组又被拆包。因为逗号分隔的值是元组的简易表示。因此可以直接用元组接收返回值:value = f()
    也可以返回一个字典达到返回多个值的功能:return {‘a’:a,‘b’:b,‘c’:c}
    dict = f()
    print(dict)
    {‘a’: 5, ‘b’: 6, ‘c’: 7}

例:将列表中的每个字符串规范化

import re  # 正则表达式模块
states = [' Alabama','Georgia!','georgia','FLOrIda','south  carolina##','West virginia?']
def normalize(string):
    s = re.sub('[!#?]','',string).strip().title()  # 连续使用多个函数,不能像R中管道函数,只能这么用
    return s
l = list(map(normalize,states))  # map函数将函数应用到序列的每一个元素,类似于R的apply,sapply
print(l)  # ['Alabama', 'Georgia', 'Georgia', 'Florida', 'South  Carolina', 'West Virginia']

note:

  • re.sub(pattern,repl,string,count = 0,flags = 0 ) 字符串替换,将string中符合pattern的字符替换为repl,count=0默认全部替换
  • [!#?]是一个字符组,表示一个位置上可以出现的字符,一个位置上出现!或#或?则替换为空串,count=0替换全部符合的位置
  • str.strip() 移除字符串两端的空格。类似的方法 .lstrip().rstrip() 。第一个是只删头,第二个是只删尾巴。
#.strip(char),.strip(string):移除字符串两端的字符或字符序列,实质是从头从尾遍历,如果字符包含在参数里就删除,遇到第一个不包含的字符就停止。
# 例如:.strip('0'),.strip('12'),.strip('hai'),只要外围碰到不需要删除的字符,屠杀就结束了。
  • .title() :返回"标题化"的字符串,字符串中的所有单词都是以大写开始,其余字母均为小写
s = "this is string example....wow!!!"
print (s.title()) 
# This Is String Example....Wow!!!

lambda函数:
非常简单的函数可以不用写函数体,而用一句话表示,使用lambda关键字,该语句的结果就是返回值.
result = lambda x:函数体 using x (x是函数参数)

# 根据单词中不同字母的数量单词排序
words = ['foo','card','aaaa','abab']
words.sort(key=lambda x:len(set(list(x))))
words  # ['aaaa', 'foo', 'abab', 'card']

Curry化
生成器和itertools模块:占坑,用到再填

9.异常处理

try:
 要执行的可能出错的代码
except:
 如果出错想采取的措施
(else:
 如果try执行成功才要执行的代码)
(finally:
 无论成功与否最后总要执行的代码)

# 输出浮点化,如果输入不能浮点化会报错,则except部分将执行,输出原值
x = 'a'
try:
    print(float(x))
except:
    print(x)
# a

注意:
1.如果只想处理某个异常类型,则在except后面加上特定异常类型,比如except ValueError:,其他异常类型仍会报错
2.可以同时处理多个异常类型,加括号写成元组,如except (ValueError,TypeError):
3.如果想无论报错与否最后都执行一部分代码,写到finally部分,比如程序与文件或数据库的连接最后总要关闭
4.如果想在try执行成功后才执行一些代码,写入else部分,作为对try执行成功的奖励
5.顺序一定是:try-except-(else)-(finally)

# 写入文件的异常处理
f = open('D:\\a.txt','w')  # 建立文件对象
try:
    f.write('123')         # 向文件写入字符串
except:
    print('Failed')        # 如果失败
else:
    print('Success')       # 如果成功写入
finally:
    f.close()              # 最后关闭文件
10.文件与操作系统
  1. 创建文件对象以读取文件:f = open(path,mode=‘r’) 默认只读模式
模式描述
‘w’只写模式:自动创建文件,覆盖同名文件
‘x’同上,存在同名文件则报错
‘r+’可读可写模式
‘a’追加写模式,不存在就自动创建

还有两个是附加选项,添加到模式后面:

  • b:以二进制形式,如’rb’
  • t: 以文本模式(默认),如’rt’
  1. 读取操作:.read() .tell() .seek()
  2. 写入文件:write()
  3. 关闭文件对象:f.close()
path = 'D:\\a.txt' # 绝对路径
f = open(path,mode='r')  #  创建文件对象,默认只读模式'r',可以看做元素是行的列表,需要显示关闭文件对象f.close()
for line in f:
    print(line)  # 打印每一行
f.close() 

更简单的使用文件对象with,在with结束时自动关闭对象,区别在于结果不会直接显示在屏幕上,需要print

with open(path) as f:
    lines = [line.rstrip() for line in f]  # 去掉右边的换行符,因为每一行以换行符\n结尾,也包括在一行里面
lines   # ["132'", 'abc/', 'opq.', '456,']
    
with open(path) as f:
    lines = [line for line in f]  
    # 或 lines = f.readlines()  读取所有行到一个列表,每行是一个元素,大文件较占内存
lines   # ["132'\n", 'abc/\n', 'opq.\n', '456,']

读取方法-文件句柄,即文件指针
使用这些方法要注意是针对字节计数的,而非ASCII码(比如汉字)可能占多个字节,要确保完整的字符被分开。

with open(path) as f:
    print(f.tell())     # tell():给出句柄当前位置,是0
    print(f.read(6))   # read(n):从当前句柄位置开始向后读取n个字节,同时推进文件句柄的位置,若无参数则读取所有字节,132'\na
    print(f.tell())     # 7,即使用默认编码情况下需要多少字节对这6个字符进行解码,换行符\n占1个字节
    print(f.seek(3))    # seek(n):改变句柄位置到第n个字节

在这里插入图片描述

# 检查系统的默认编码
import sys
sys.getdefaultencoding()  # 'utf-8'

# 查看在某编码下字符占多少字节
len("132'\na".encode('utf-8'))    # 'gbk'
编码方式

将字符串data解码为某种编码:data.decode(‘one encoding’)
常用编码方式:‘utf-8’,‘gbk’
open(path=,mode=’’,encoding=’’)中encoding可以方便将文件转换为另一种编码

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值