python基础笔记2:部分数据类型与函数

type 的 type:

a = 1
print(type(type(a)))
s = type(a)
print(f'type = {s}')

# <class 'type'>
# type = <class 'int'>         可见type自身是一种类型,不是str但是可以转化成str

li = [2, '3', 2333, 6.0]
for i in li:
	if type(i) == int:
        print(i)         # 2   2333       函数类型关键字也是type类型的,可直接用于比较

复数

x = complex(3, 2)
y = 4j
y += 1
z = complex(0, 3)
print(x, y, z)       # (3+2j) (1+4j) 3j

浮点数

import math

round(0.5)  # 0
round(1.5)  # 2
round(2.5)  # 2
round(3.5)  # 4
round(4.5)  # 4
round(5.5)  # 6
round(6.5)  # 6     由于pyhon以浮点类型存储数据,故round函数四舍五入有误差

round(2.5+0.000001) # 3   必须加一个eps才能解决

round(1.35, 1) #1.4   保留小数点后1位

字符串

s = r'a%2b\n%d\n'
for c in s:
    print(c, end='')  # a%2b\n%d\n    字符串前加r忽视特殊字符
   
s = u'中文'            # unicode

s = b'asdf'
print(type(s))        # <class 'bytes'>   加b转成bytes类型
print(s)              # b'asdf'
S = s.decode('utf-8')
print(S)              # asdf

s = '中文'
B = s.encode()        # bytes类型为str encode后的格式,逆运算是decode解码
print(B)              # b'\xe4\xb8\xad\xe6\x96\x87'

age = 18
s = f'age = {age}'    # 格式化字符串

ljust 与 rjust 补齐:

print('123'.ljust(6,'L'))    # 123LLL
print('123'.rjust(6,'0'))    # 000123 补齐前导零

strip():

s = '   qwq   \n\n  QAQ  \n   '
print(s.strip())
# qwq   
#  QAQ         strip可以去掉字符串首尾的空格和回车,也可以传参指定字符s.strip('\n')

s = '1213124565432121'
print(s.strip('12'))
# 312456543      也可以去除指定字符串,注意到三点:1、末尾倒序;2、中间不会去掉;3、匹配一半也会删除

s = '0010100819200'
print(s.lstrip('0'))
# 10100819200     去除前导零,用lstrip

split():

s = '1234 23 ;;;2    .2. 23. df'
li = s.split()
print(li)     # ['1234', '23', ';;;2', '.2.', '23.', 'df']  
#   split是str类的方法,返回值为list,默认是按空格和回车切割好的字符串,也可以指定切割的字符(或字符串)
li2 = s.split('.')
print(li2)    # ['1234 23 ;;;2     ', '2', ' 23', ' df']   注意:默认的分割方式会删去空字符串,而自定义不会

# 第二个参数是分割几次:剩余的未分割完的字符串会整个塞入list

想要同时用' '和'.'来分割? 需要用re库里的split实现扩展功能:

s = '23. .2.1'
fu = [' ', '.']
num_list = re.split(f'{fu}',s)
print(num_list)   # ['23', '', '', '2', '2']

提取文件中所有数字:

文本读取:

with open(r'1.txt', 'r') as file:
    all = file.read()         # all 是一个str,包含'\n'
    lines = file.readlines()  # lines 是一个list,元素为每行字符串(末尾都是'\n')
# 注:read是不能重复读的,两个只能写一个,这个写法lines是空的

lines = all.split('\n')  # 其实可以用split把它俩联系起来,区别在于此时的lines元素末尾没有了'\n'

言归正传:

with open(r".\1.txt") as file:
    all = file.read()
s = ''
for c in all:
    if c<'0' or c>'9':       # 冗余字符全替换为空格
        s += ' '
    else:
        s += c

s_list = s.split(' ')
num_list = []
for n in s_list:
    if n != '':        # 判断空字符串
        num_list.append(int(n))  # 转成int,可以自动去除前导零
print(num_list)
# 这个程序只能分割所有非负整数,带负号和小数点无法处理,需要自行对字符串进行判断

sort & sorted

sort()函数只有list类型才有,返回值为None,是将list内部排序的void函数,可传参:reverse。

sorted() 传参可以是任意iterable,不改变原iterable,返回值恒定为排好的list

a = [1, 3, 6, 2, 4]
a.sort(reverse=True)
print(a)       # [6, 4, 3, 2, 1]

s = 'asdf'
z = sorted(s)
print(s,z)     # asdf ['a', 'd', 'f', 's']

字典排序:

dic = {'c': 4, 'a': 5, 'd': 1, 'b': 2}
li1 = sorted(dic)
print(li1)                    # ['a', 'b', 'c', 'd']    直接排序是只对键排序

li2 = sorted(dic.items())
print(li2)      			  # [('a', 5), ('b', 2), ('c', 4), ('d', 1)]  # 转化为元组排序,默认按第一关键字

li3 = sorted(dic.items(), key=lambda x: x[1], reverse=True)
print(li3)                    # [('a', 5), ('c', 4), ('b', 2), ('d', 1)]  根据第二关键字排序

python2中sorted可以传四个参数:sorted(iterable, cmp, key, reverse)

python3中却缩减到了三个参数:sorted(iterable, key, reverse)

在C++中习惯用cmp进行sort的话会感到很不舒服,不过我们可以用functools库中的cmp_to_key来实现cmp转key。

有了这个函数,我们的key值就可以随心所欲地定义了:

from functools import cmp_to_key
dic = {'e': 4, 'a': 5, 'd': 1, 'b': 2, 'c': 4}


def cmp1(x, y):     # 可以实现先按第二关键字排序再按第一关键字排序
    if x[1] != y[1]:
        return -1 if x[1] < y[1] else 1
    else:
        return -1 if x[0] < y[0] else 1


li4 = sorted(dic.items(), key=cmp_to_key(cmp1))
print(li4)        #[('d', 1), ('b', 2), ('c', 4), ('e', 4), ('a', 5)]

key参数传进去的是一个函数对象,用于将原数组按照这个函数操作后再进行大小比较,函数不会影响原序列中的值。

常见用法有 len, int, str, lower 等,分别表示按字符串长度排序,字符串转成int或str排序,忽略大小写字母排序:

numl = [12, 15, 93, 45, 42, 12, 32, 23, 51, 41]
numl.sort(key = lambda a : a//10)
# 按十位数排序

str1 = 'aASDfaWEFasDFAwsedFAwdseoianf'

def func(c):
	if c>='a':
		c = chr(ord(c)+ord('A')-ord('a'))
	return c

str2 = sorted(str1, key=func)
# 自定义函数的排序

filter & map

# filter()可以从序列中过滤出符合条件的元素,保留函数值为1的量,保存到一个新的序列中
l = [1,2,3,4,5,6,7,8,9,10]
r = filter(lambda i : i > 5 , l)    # [6, 7, 8, 9, 10]

def qwq(a):
    return a & 1

r = filter(qwq , l)   # [1, 3, 5, 7, 9]
print(list(r))
# 注意:1.filter和map不需要像sort那样写 'key='  2.返回值均为可迭代序列,而不是是list,需要强转

r = map(lambda i : i ** 2 , l)
# map用于对原序列做一一映射后赋值到一个新对象中

r = map(int, input().split())
print(list(r))
# 用于输入一行并按空格拆分所有整数,非常有用!

不定长参数

def sum(*nums):
    result = 0
    for n in nums :
        result += n
    print(result)

sum(123,456,789,10,20,30,40)

# *args接受所有实参,统一保存至元组
# **kwargs接受所有形参,统一保存至字典
def new_function(*args , **kwargs):


def func(a, b, c)
t = (123, 20, 11111)
func(*t)
# 传递实参加星号用于解包(拆包)

d = {'a':100,'b':200,'c':300}
# 通过 **来对一个字典进行解包操作,只保留value值
func(**d)

命名空间与闭包

n = 101010
print(locals())
scope = locals()
scope['m'] = 202020
# locals函数用于显示当前作用域下所有变量字典,可以往字典中直接添加键值对但是不推荐

#{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': 
<_frozen_importlib_external.SourceFileLoader object at 0x0000028942FB72B0>,
 '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>,
 '__file__': 'asdf.py', '__cached__': None, 'asdf': <function asdf at 0x0000028943014E50>,
 'n': 101010}

命名空间从外向内,内部可查看外部,外部无法查看内部,内部查看外部变量需要加global或者nonlocal:

闭包:内部变量外部调用,可以防止外部作用域同变量名被修改

def asdf():

	li = []
	sm = 0

	def add(i):
		nonlocal sm
		print(locals())
		
		li.append(i)
		sm += i
		return sm

	return add


wo = asdf()

print(wo(5))
print(wo(8))
# {'i': 5, 'li': [], 'sm': 0}
# 5
# {'i': 8, 'li': [5], 'sm': 5}
# 13

# sm需要nonlocal否则会显示使用前未声明,li却不用因为解释器看完函数发现有个append就把它自动移进来了(大概)

def sumer():

	sm = 0
	li = []

	def add(i):
		nonlocal sm
		sm += i
		return sm

	def mul(i):
		nonlocal sm
		sm *= i
		return sm

	def delet(i):
		nonlocal sm
		sm -= i
		return sm

	return {'add':add, 'mul':mul, 'delet':delet}
	return add

wo = sumer()
print(wo['add'](5))
print(wo['add'](6))
print(wo['mul'](10))

装饰器

需要对某几个函数进行拓展装饰时,可以套一层壳。

比如下面就是对函数进行开始和结束的注释输出:

def begin_end(old):
    
    def new_function(*args , **kwargs):
        print('开始执行~~~~')
        result = old(*args , **kwargs)
        print('执行结束~~~~')
        return result
      
    return new_function

f = begin_end(fn)
f2 = begin_end(add)
f3 = begin_end(mul)

r = f()
r = f2(123,456)
r = f3(123,456)

# *args , **kwargs 可以保证各种类型的参数都能传进去,不受装饰函数本身参数影响
posted @ 2023-09-06 00:38  maple276  阅读(29)  评论(0)    收藏  举报