python基础知识整理一(持续更新中)


1. ord()函数获取字符的整数表示, chr()函数把编码转换为对应的字符:

>>> 'Hello, %s' % 'world'                     
 'Hello, world
'>>> 'Hi, %s, you have $%d.' % ('Michael', 1000000)       
 ‘Hi, Michael, you have $1000000.'

2. %s永远起作用,它会把任何数据类型转换为字符串:

>>> 'Age: %s. Gender: %s' % (25, True)
'Age: 25. Gender: True'

3.%%来表示一个%

>>> 'growth rate: %d %%' % 7
    'growth rate: 7 %'

4. 使用字符串的format()方法,它会用传入的参数依次替换字符串内的占位符{0}、{1}……,不过这种方式写起来比%要麻烦得多:

>>> 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
'Hello, 小明, 成绩提升了 17.1%'

5. 由于Python源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这两行:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;
第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。

6. 最后一种格式化字符串的方法是使用以f开头的字符串,称之为f-string,它和普通字符串不同之处在于,字符串如果包含{xxx},就会以对应的变量替换:

>>> r = 2.5
>>> s = 3.14 * r ** 2
>>> print(f'The area of a circle with radius {r} is {s:.2f}')
The area of a circle with radius 2.5 is 19.62

上述代码中,{r}被变量r的值替换,{s:.2f}被变量s的值替换,并且:后面的.2f指定了格式化参数(即保留两位小数),因此,{s:.2f}的替换结果是19.62。

7. 编码问题
由于最初的计算机由美国人发明,字符只有127个,所以如果有的中文无法被表示,或者说是占用的内存过长。中文如此,其他国家语言亦是如此。但是如果每个国家都有属于自己的编码,就需要浪费大量的人力物力,因此,Unicode字符集应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。新的问题又出现了:如果统一成Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间。UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分。在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件:在这里插入图片描述
浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器:
在这里插入图片描述
8. 要计算str包含多少个字符,可以用len()函数,如果换成byteslen()函数就计算字节数。

>>> len('ABC')
3
>>> len('中文')
2

>>> len(b'ABC')
3
>>> len(b'\xe4\xb8\xad\xe6\x96\x87')
6
>>> len('中文'.encode('utf-8'))
6

可见,一个中文字符经过UTF-8编码后通常会占用3个字节,而1个英文字符只占用1个字节。

list

>>> classmates = ['Michael', 'Bob', 'Tracy']
>>> classmates
['Michael', 'Bob', 'Tracy']


>>> len(classmates)
3
>>> classmates[0]
'Michael'
>>> classmates[1]
'Bob'
>>> classmates[2]
'Tracy'
>>> classmates[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range


>>> classmates[-1]
'Tracy'
>>> classmates[-2]
'Bob'
>>> classmates[-3]
'Michael'
>>> classmates[-4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range


>>> classmates.append('Adam')
>>> classmates
['Michael', 'Bob', 'Tracy', 'Adam']


>>> classmates.insert(1, 'Jack')
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy', 'Adam']


>>> classmates.pop()
'Adam'
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy']


>>> classmates.pop(1)
'Jack'
>>> classmates
['Michael', 'Bob', 'Tracy']

>>> aList = [123, 'xyz', 'zara', 'abc', 'xyz'];
>>> aList.remove('xyz');
[123, 'zara', 'abc', 'xyz']


>>> classmates[1] = 'Sarah'   ##替换某一个元素
>>> classmates
['Michael', 'Sarah', 'Tracy']


>>> L = ['Apple', 123, True] #list中的元素可以不同


>>> s = ['python', 'java', ['asp', 'php'], 'scheme'] # 要注意s只有4个元素,其中s[2]又是一个list,
>>> len(s)
4
>>> p = ['asp', 'php']
>>> s = ['python', 'java', p, 'scheme']


>>> L = []    # 空列表
>>> len(L)


cars=['bmw','audi','toyota','subaru']
cars.sort();   ##永久排序,从小到大
cars.sort(reverse=True)  ##永久排序,从大到小
cars.sorted()     ##临时排序
cars.reverse()    ## 倒着打印列表,并非排序

tuple

tuplelist非常类似,但是tuple一旦初始化就不能修改

classmates = ('Michael', 'Bob', 'Tracy')

现在,classmates这个tuple不能变了,它也没有append()insert()这样的方法。其他获取元素的方法和list是一样的,你可以正常地使用classmates[0]classmates[-1],但不能赋值成另外的元素。不可变的tuple有什么意义?因为tuple不可变,所以代码更安全。

>>> t = (1, 2)  ##当你定义一个tuple时,在定义的时候,tuple的元素就必须被确定下来
>>> t
(1, 2)

>>> t = ()  ##空tuple
>>> t
()
>>> t = (1)
>>> t
1

定义的不是tuple,是1这个数!这是因为括号()既可以表示tuple,又可以表示数学公式中的小括号,这就产生了歧义,因此,Python规定,这种情况下,按小括号进行计算,计算结果自然是1。所以,只有1个元素的tuple定义时必须加一个逗号,来消除歧义:

>>> t = (1,)
>>> t
(1,)

Python在显示只有1个元素的tuple时,必须在这个元素后面加一个逗号,以免你误解成数学计算意义上的括号。

>>> t = ('a', 'b', ['A', 'B'])  ##“可变的”tuple
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])

条件判断

age = 20   ##根据Python的缩进规则,如果if语句判断是True,就把缩进的两行print语句执行了,否则,什么也不做。
if age >= 18:
    print('your age is', age)
    print('adult')


age = 3
if age >= 18:
    print('your age is', age)
    print('adult')
else:
    print('your age is', age)
    print('teenager')


age = 3
if age >= 18:
    print('adult')
elif age >= 6:
    print('teenager')
else:
    print('kid')

if <条件判断1>:
    <执行1>
elif <条件判断2>:
    <执行2>
elif <条件判断3>:
    <执行3>
else:
    <执行4>



birth = input('birth: ')
if birth < 2000:
    print('00前')
else:
    print('00后')

输入1982,结果报错,这是因为input()返回的数据类型是strstr不能直接和整数比较,必须先把str转换成整数。Python提供了int()函数来完成这件事情。

s = input('birth: ')
birth = int(s)
if birth < 2000:
    print('00前')
else:
    print('00后')

循环

sum = 0
for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
    sum = sum + x
print(sum)

Python提供一个range()函数,可以生成一个整数序列,再通过list()函数可以转换为list。比如range(5)生成的序列是从0开始小于5的整数:

>>> list(range(5))
[0, 1, 2, 3, 4]

range(1,6)  #1、2、3、4、5
range(2,11,2)  #2、4、6、8、10
sum = 0
n = 99
while n > 0:
    sum = sum + n
    n = n - 2
print(sum)       #while循环

n = 1
while n <= 100:
    if n > 10: # 当n = 11时,条件满足,执行break语句
        break # break语句会结束当前循环
    print(n)
    n = n + 1
print('END')    ##break作用是提前结束循环

n = 0
while n < 10:
    n = n + 1
    if n % 2 == 0: # 如果n是偶数,执行continue语句
        continue  # continue语句会直接继续下一轮循环,后续的print()语句不会执行
    print(n)      #continue提前结束本轮循环,打印的不再是1~10,而是1,3,5,7,9。      

要特别注意,不要滥用breakcontinue语句。breakcontinue会造成代码执行逻辑分叉过多,容易出错。大多数循环并不需要用到breakcontinue语句,上面的两个例子,都可以通过改写循环条件或者修改循环逻辑,去掉breakcontinue语句。
有些时候,如果代码写得有问题,会让程序陷入“死循环”,也就是永远循环下去。这时可以用Ctrl+C退出程序,或者强制结束Python进程。

dict

dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。

names = ['Michael', 'Bob', 'Tracy']
scores = [95, 75, 85]
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d['Michael']
95

dict的实现方式就是给定一个名字,比如’Michael'dict在内部就可以直接计算出Michael对应的存放成绩的“页码”,也就是95这个数字存放的内存地址,直接取出来,所以速度非常快。

>>> d['Adam'] = 67
>>> d['Adam']
67      ## 通过key把数据放入dict
 
 
>>> d['Jack'] = 90
>>> d['Jack']
90
>>> d['Jack'] = 88
>>> d['Jack']
88   ##一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉


>>> d['Thomas']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'Thomas'    ##key不存在,会报错


>>> 'Thomas' in d
False    ##通过in判断ke是否存在

>>> d.get('Thomas')
>>> d.get('Thomas', -1)
-1     ##通过dict提供的get()方法,如果key不存在,可以返回None,或者自己指定的value,返回None的时候Python的交互环境不显示结果。


>>> d.pop('Bob')
75
>>> d
{'Michael': 95, 'Tracy': 85}   ##删除key用pop()函数,跟数据结构与算法中的pop函数相似

del('Bob')   ##删除键值对也可以用del函数

for key.value in d.items():
	print(f"key:{key}")
	print(f"alue:{value}")   ##遍历所有键值对


for name in d.keys():     ##遍历所有键
	print(name.title())

for name in d.keys():     ##遍历所有值
	print(name.title())

dict内部存放的顺序和key放入的顺序是没有关系的。
和list比较,dict有以下几个特点
查找和插入的速度极快,不会随着key的增加而变慢;
需要占用大量的内存,内存浪费多。
而list相反
查找和插入的时间随着元素的增加而增加;
占用空间小,浪费内存很少。

所以,dict是用空间来换取时间的一种方法。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key

>>> key = [1, 2, 3]
>>> d[key] = 'a list'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

set

setdict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key

>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}   ##要创建一个set,需要提供一个list作为输入集合


>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}   ##重复元素在set中自动被过滤


>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> s.add(4)
>>> s
{1, 2, 3, 4}    ##通过add(key)方法可以添加元素到set中,可以重复添加,但不会有效果


>>> s.remove(4)
>>> s
{1, 2, 3}       ##通过remove(key)方法可以删除元素

set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:

>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}
>>> a = 'abc'
>>> a.replace('a', 'A')
'Abc'
>>> a
'abc'      ##replace用法
>>> a = 'abc'
>>> b = a.replace('a', 'A')
>>> b
'Abc'
>>> a
'abc'

调用函数

>>> abs(100)
100
>>> abs(-20)
20
>>> abs(12.34) 
12.34        ##绝对值函数


>>> a = abs # 变量a指向abs函数
>>> a(-1) # 所以也可以通过a调用abs函数
1


>>> abs(1, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: abs() takes exactly one argument (2 given)    ##abs()有且仅有1个参数

>>> abs('a')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bad operand type for abs(): 'str'    ##str是错误的参数类型


>>> max(1, 2)
2
>>> max(2, 3, 1, -5)
3    ##函数max()可以接收任意多个参数,并返回最大的那个

数值类型转换

>>> int('123')
123
>>> int(12.34)
12
>>> float('12.34')
12.34
>>> str(1.23)
'1.23'
>>> str(100)
'100'
>>> bool(1)
True
>>> bool('')
False

定义函数

定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。

def my_abs(x):
    if x >= 0:
        return x
    else:
        return -x

如果没有return语句,函数执行完毕后也会返回结果,只是结果为None。return None可以简写为return。

空函数

def nop():
    pass

pass语句什么都不做,那有什么用?实际上pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来。

if age >= 18:
    pass        ##缺少了pass,代码运行就会有语法错误。

参数检查

调用函数时,如果参数个数不对,Python解释器会自动检查出来,并抛出TypeError
但是如果参数类型不对,Python解释器就无法帮我们检查。试试my_abs和内置函数abs的差别:

>>> my_abs('A')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in my_abs
TypeError: unorderable types: str() >= int()
>>> abs('A')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bad operand type for abs(): 'str'

当传入了不恰当的参数时,内置函数abs会检查出参数错误,而我们定义的my_abs没有参数检查,会导致if语句出错,出错信息和abs不一样。所以,这个函数定义不够完善。
修改一下my_abs的定义,对参数类型做检查,只允许整数和浮点数类型的参数。数据类型检查可以用内置函数isinstance()实现:

def my_abs(x):
    if not isinstance(x, (int, float)):
        raise TypeError('bad operand type')
    if x >= 0:
        return x
    else:
        return -x

>>> my_abs('A')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in my_abs
TypeError: bad operand type

返回多个值

import math

def move(x, y, step, angle=0):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny

>>> r = move(100, 100, 60, math.pi / 6)
>>> print(r)
(151.96152422706632, 70.0)

Python的函数返回多值其实就是返回一个tuple

函数的参数

位置参数

对于power(x)函数,参数x就是一个位置参数。当我们调用power函数时,必须传入有且仅有的一个参数x:

def power(x):
    return x * x
 >>> power(5)
25
>>> power(15)
225


def power(x, n):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s           ##power(x, n)函数用来计算x的n次


>>> power(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: power() missing 1 required positional argument: 'n'       ##调用函数power()缺少了一个位置参数n

默认参数

在python内置函数中,pow(x,y)用于计算x的y次方,用此函数前需要import math

def power(x, n=2):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s
>>> pow(5,2)
   25

设置默认参数时,有几点要注意
一是必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);
二是如何设置默认参数。当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
使用默认参数最大的好处是能降低调用函数的难度。

def enroll(name, gender):
    print('name:', name)
    print('gender:', gender)
>>> enroll('Sarah', 'F')
name: Sarah
gender: F


def enroll(name, gender, age=6, city='Beijing'):
    print('name:', name)
    print('gender:', gender)
    print('age:', age)
    print('city:', city)
    
>>> enroll('Sarah', 'F')
name: Sarah
gender: F
age: 6
city: Beijing       ##大多数学生注册时不需要提供年龄和城市,只提供必须的两个参数


enroll('Bob', 'M', 7)
enroll('Adam', 'M', city='Tianjin')     ##只有与默认参数不符的学生才需要提供额外的信息:
>>> add_end()
['END']
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']

每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。
定义默认参数要牢记一点:默认参数必须指向不变对象!

要修改上面的例子,我们可以用None这个不变对象来实现

def add_end(L=None):
    if L is None:
        L = []
    L.append('END')
    return L
>>> add_end()
['END']
>>> add_end()
['END']

设计str、None这样的不变对象是因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。

可变参数

def calc(numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum


>>> calc([1, 2, 3])
14
>>> calc((1, 3, 5, 7))
84               ##调用的时候,需要先组装出一个list或tuple

>>> calc(1, 2, 3)
14
>>> calc(1, 3, 5, 7)
84           ##利用可变参数,调用函数的方式可以简化成这样


def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum         ##我们把函数的参数改为可变参数

定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号。调用该函数时,可以传入任意个参数,包括0个参数。

>>> calc(1, 2)
5
>>> calc()
0
>>> nums = [1, 2, 3]
>>> calc(nums[0], nums[1], nums[2])
14

>>> nums = [1, 2, 3]
>>> calc(*nums)
14      ##*nums表示把nums这个list的所有元素作为可变参数传进去。
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

poggioxay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值