Python学习笔记1:基础
Python学习笔记1:基础知识
Python解释器
Skill 1
转盘符时不用输入cd,盘符内跳转文件夹才用cd。我把.py文件放在e盘,建好.py文件后要先输入e: 跳转到e盘,然后再用cd e:\文件夹名 跳转到文件夹。
如:从C盘直接转到E盘时直接输入:
E:
从E盘定位到E盘下的文件夹,输入:
cd: E:\文件夹名\文件夹名
python字符串
几个函数:
ord()
- 获取字符的整数表示
chr()
- 把编码转化为对应字符
- Python 对bytes类型的数据用带b前缀的单引号或双引号表示
encode()
- 编码
decode()
- 解码
\x##
- 无法显示为ASCII编码
len()
- 计算
str
的字符数 - 两行注释:
#!usr/bin/env python3 # _*_coding: utf-8 _*_
%
表示 占位符, 其中%d
整数,%f
浮点数,%s
字符串,%x
十六进制整数.%s
会将任何数据类型转化为字符串,format()
用传入的参数依次替换字符串内的占位符{0}
、{1}
等,f-string
和普通字符串不同之处在于,字符串如果包含{xxx}
,就会以对应的变量替换
# 占位符示例 >>> 'Hello, %s' % 'world' 'Hello, world' # 字符串占位符及整数占位符示例 >>> 'Hi, %s, you have $%d.' % ('Michael', 1000000) 'Hi, Michael, you have $1000000.' # 格式化整数和浮点数,如: 是否补0, 定义小数位数 >>> print('%2d-%02d' % (3, 1)) >>> print('%.2f' % 3.1415926) 3-01 3.14 #利用 s% 占位 >>> 'Age: %s. Gender: %s' % (25, True) 'Age: 25. Gender: True' # 利用 %% 转义字符 >>> 'growth rate: %d %%' % 7 'growth rate: 7 %' # 利用 format()格式化 >>> 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125) 'Hello, 小明, 成绩提升了 17.1%' # 利用f-string格式化 >>> 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
List 和 tuple
- list 有序集合, 可增删其中的元素, tuple 有序集合,不可随意增删其中的元素. 其中, 每个list和tuple均可包含其他的list或tuple
list. append('xxx')
, 追加元素'xxx'至末尾list [0], list[1]
. 访问索引位置为1,2 的元素. Python中元素索引从 0 开始, 即 索引位置0 代表第1位元素list[-1]
, 访问倒数第1位的元素pop(i)
, 删除索引位置为i的元素, pop() 表示删除末位元素list[i]= 'XYZ'
, 将XYZ赋值于索引位置为i的元素, 即替换索引位置为i的元素为'XYZ'
>>> s = ['python', 'java', ['asp', 'php'], 'scheme']
- 要拿到
'php'
可以写p[1]
或者s[2][1]
- 要定义只有一个元素的tuple时,必须加逗号
,
>>> t = (1,) >>> t (1,)
条件判断
if()
else()
elif()
执行条件判断,从上到下依次进行判断并输出结果,举例:
age = 20 if age >= 6: print('teenager') elif age >= 18: print('adult') else: print('kid')
注意: 条件判断语句末尾的冒号:
不能丢掉
另外, 条件判断中的错误示例,本示例中注意代码前两行:
s = input('birth: ') birth = int(s) if birth < 2000: print('00前') else: print('00后')
如果省略第二行,直接输入年份会报错, 因为input()
返回的数据类型是str
,str
不能直接和整数比较,必须先把str
转换成整数。Python提供了int()
函数来完成这件事情.所以,应当转化str
为int
或其他变量类型.
循环语句
for x in ...
循环就是把每个元素代入变量x
,然后执行缩进块的语句
L = ['Bart', 'Lisa', 'Adam'] for name in L: print ('Hello,',name, '!')
上面这段代码的运行结果是:
Hello, Bart ! Hello, Lisa ! Hello, Adam !
需要注意的是最后一行的print语句, 要想输出上面的结果,必须在不同的变量中间加逗号,
.不然无法将name
识别为变量.也就是说,变量和字符串之间一定要有区分,不然无法被计算机识别.
在print('Hello,' , name, '!')
语句中, name
是一个变量而非str, 所以 name不需要加括号写成(name)
.
- Python提供一个
range()
函数,可以生成一个整数序列,再通过list()
函数可以转换为list。比如range(5)
生成的序列是从0开始小于5的整数:
>>> list(range(5)) [0, 1, 2, 3, 4]
注意:代码块之间的缩进
- while循环,只要条件满足,就不断循环,条件不满足时退出循环。
n = 0 while n < 101: n = n +1, print(n)
- break 语句: 中止循环
n = 1 while n <= 100: if n > 10: # 当n = 11时,条件满足,执行break语句 break # break语句会结束当前循环 print(n) n = n + 1 print('END')
- continue 语句:提前结束本轮循环,并直接开始下一轮循环。
n = 0 while n < 10: n = n + 1 if n % 2 == 0: # 如果n是偶数,执行continue语句 continue # continue语句会直接继续下一轮循环,后续的print()语句不会执行 print(n)
小结
循环是让计算机做重复任务的有效的方法。
break
语句可以在循环过程中直接退出循环,而continue
语句可以提前结束本轮循环,并直接开始下一轮循环。这两个语句通常都必须配合if
语句使用。
要特别注意,不要滥用break
和continue
语句。break
和continue
会造成代码执行逻辑分叉过多,容易出错。
有些时候,如果代码写得有问题,会让程序陷入“死循环”,也就是永远循环下去。这时可以用Ctrl+C
退出程序,或者强制结束Python进程。
使用dict和set
Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。要创建一个set,需要提供一个list作为输入集合.
- dict
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85} >>> d['Michael'] 95 >>> 'Thomas' in d #判断某一个key是否在 dict中 False >>> d.get('Thomas') #获取某一个key, 不存在此key返回none(注意:python中空值不显示) >>> d.get('Thomas', -1) #获取某一个key, 不存在此key返回指定值 -1 >>> d.pop('Bob') #删除某一个key及其对应的value 75 >>> d {'Michael': 95, 'Tracy': 85}
- set
>>> s = set([1, 2, 3]) #定义一个set >>> s {1, 2, 3} >>> s = set([1, 1, 2, 2, 3, 3]) >>> s {1, 2, 3} #返回值不重复 >>> s.add(4) #增加一个key至set中 >>> s {1, 2, 3, 4} >>> s.remove(4) #从set中移除一个key >>> s {1, 2, 3} >>> s1 = set([1, 2, 3]) >>> s2 = set([2, 3, 4]) >>> s1 & s2 #求两个set的交集 {2, 3} >>> s1 | s2 #求两个set的并集 {1, 2, 3, 4}
关于哈希表
要理解dict的有关内容需要你理解哈希表(map)的相关基础知识,这个其实是《算法与数据结构》里面的内容。
1.list和tuple其实是用链表顺序存储的,也就是前一个元素中存储了下一个元素的位置,这样只要找到第一个元素的位置就可以顺藤摸瓜找到所有元素的位置,所以list的名字其实就是个指针,指向list的第一个元素的位置。list的插入和删除等可以直接用链表的方式进行,比如我要在第1个元素和第2个元素中间插入一个元素,那么直接在链表的最后面(我们假设这个list只有两个元素,那么也就是在第3个元素的位置上)插入这个元素,然后把第一个元素指针指向这个元素(第3个位置),然后再把新插入的元素的指针指向原来的第2个元素,这样插入操作就完成了。读取这个list的时候,先用list的名字(就是个指针,指向第1个元素的位置)找到第一个元素,然后用第1一个元素的指针找到第2个元素(位置3),然后用第2个元素的指针找到第3个元素(位置2),以此类推。所以list的顺序和内存中的实际顺序其实不一定完全对应。这种存储方式不会浪费内存,但查找起来特别费时间,因为要按照链表一个一个找下去,如果你的list特别大的话,那么要等好久才会找到结果。
2.dict则为了快速查找使用了一种特别的方法,哈希表。哈希表采用哈希函数从key计算得到一个数字(哈希函数有个特点:对于不同的key,有很大的概率得到的哈希值也不同),然后直接把value存储到这个数字所对应的地址上,比如key='ABC',value=10,经过哈希函数得到key对应的哈希值为123,那么就申请一个有1000个地址(从0到999)的内存,然后把10存放在地址为123的地方。类似的,对于key='BCD',value=20,得到key的哈希值为234,那么就把20存放在地址为234的地方。对于这样的表查找起来是非常方便的。只要给出key,计算得到哈希值,然后直接到对应的地址去找value就可以了。无论有几个元素,都可以直接找到value,无需遍历整个表。不过虽然dict查找速度快,但内存浪费严重,你看我们只存储了两个元素,都要申请一个长度为1000的内存。
3.现在你知道为啥key要用不可变对象了吧?因为不可变对象是常量,每次的哈希值算出来都是固定的,这样就不会出错。比如key='ABC',value=10,存储地址为123,假设我突发奇想,把key改成'BCD',那么当查找'BCD'的value的时候就会去234的地址找,但那里啥也没有,这就乱套了。
3.你看我们上面有一句话:对于不同的key,有很大的概率得到的哈希值也不同。那么有很小的概率不同的key可以得到相同的哈希值了?没错,比如对于我们的例子来说,哈希值只有3位,那么只要元素个数超过1000,就一定会有至少两个key的哈希值相同(鸽笼原理),这种情况叫“冲突”,设计哈希表的时候要采取办法减少冲突,实在冲突了也要想办法补救。不过这是编译器的事情,况且对于初学者的我们来说碰到的冲突的概率基本等于零,就不用操心了。