一直觉得大蟒蛇是非常强大的语言,经过几次学习还是没有摸到什么门路,这次静下心来记录一下,希望能有个不错的收穫,人生苦短,我学python。
作为一个4年的前端,js写的还算比较6,所以经常无意识的给末尾加分号,不知道学一阵子大蟒蛇之后会不会习惯了不写分号bug了我js - -|||
so here we go.
包含内容:输入,输出,基础用法,数据类型,字符串编码,格式化,list和tuple,条件判断,循环,dict类型,set类型,函数,空函数,递归函数
输入
print()可以接受多个字符串使用逗号隔开。
print('hello','world')
可以运。
输出
input()在运行之后允许用户输入,之后可以赋值给变量,再次打印变量将得到用户输入的结果。
基础用法
缩进写法,不需要尾分号,#号为注释,冒号结尾缩紧的语句是代码段。
# print absolute value of an integer: a = 100 if a >= 0: print(a) else: print(-a)
数据类型
python能直接处理的数据类型:
整数,浮点数,字符串,布尔值,空值,变量,常量
整数 正负二进制
浮点数
整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的(除法难道也是精确的?是的!),而浮点数运算则可能会有四舍五入的误差。
字符串
可以用转义 单引号 双引号完全一致 三引号定义多行内容
>>> print('''line1 ... line2 ... line3''')
布尔值
布尔值和布尔代数的表示完全一致,一个布尔值只有True
、False
两种值,要么是True
,要么是False
,在Python中,可以直接用True
、False
表示布尔值(请注意大小写),也可以通过布尔运算计算出来
空值
空值是Python里一个特殊的值,用None
表示。None
不能理解为0
,因为0
是有意义的,而None
是一个特殊的空值。
此外,Python还提供了列表、字典等多种数据类型,还允许创建自定义数据类型。
变量
字母数字下划线,不能数组开头,直接定义,可以反复赋值,可以改变类型
常量
也是变量,只是统一使用大写规定。
字符串编码
对于单个字符的编码,Python提供了ord()
函数获取字符的整数表示,chr()
函数把编码转换为对应的字符
>>> ord('A') 65 >>> ord('中') 20013 >>> chr(66) 'B' >>> chr(25991) '文'
格式化
在Python中,采用的格式化方式和C语言是一致的,用%
实现
>>> 'Hello, %s' % 'world' 'Hello, world' >>> 'Hi, %s, you have $%d.' % ('Michael', 1000000) 'Hi, Michael, you have $1000000.'
常见的占位符有:
%d | 整数 |
%f | 浮点数 |
%s | 字符串 |
%x | 十六进制整数 |
如果不太确定应该用什么,%s
永远起作用,它会把任何数据类型转换为字符串
有些时候,字符串里面的%
是一个普通字符怎么办?这个时候就需要转义,用%%
来表示一个%
使用list和tuple
list是一种有序的集合,可以随时添加和删除其中的元素。
len()可以获取个数
append()添加
insert()可以添加指定索引的位置
pop()删除list末尾或者指定索引的元素
要把某个元素替换成别的元素,可以直接赋值给对应的索引位置
tuple
tuple和list非常类似,但是tuple一旦初始化就不能修改
只有一个元素的tuple需加一个逗号消除歧义
atuple = (1,)
tunple的元素是一个list是可以改变list值的
条件判断
if <条件判断1>:
<执行1>
elif <条件判断2>:
<执行2>
elif <条件判断3>:
<执行3>
else:
<执行4>
循环
Python的循环有两种,一种是for...in循环,依次把list或tuple中的每个元素迭代出来。
把每个元素代入变量,然后执行缩进块的语句。
第二种循环是while循环,只要条件满足,就不断循环,条件不满足时退出循环。
break
在循环中,break
语句可以提前退出循环。
continue
在循环过程中,也可以通过continue
语句,跳过当前的这次循环,直接开始下一次循环。
循环是让计算机做重复任务的有效的方法。
break
语句可以在循环过程中直接退出循环,而continue
语句可以提前结束本轮循环,并直接开始下一轮循环。这两个语句通常都必须配合if
语句使用。
要特别注意,不要滥用break
和continue
语句。break
和continue
会造成代码执行逻辑分叉过多,容易出错。大多数循环并不需要用到break
和continue
语句,上面的两个例子,都可以通过改写循环条件或者修改循环逻辑,去掉break
和continue
语句。
有些时候,如果代码写得有问题,会让程序陷入“死循环”,也就是永远循环下去。这时可以用Ctrl+C
退出程序,或者强制结束Python进程。
dict
Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d['Michael']
95
要避免key不存在的错误,有两种办法,一是通过in
判断key是否存在。
二是通过dict提供的get方法,如果key不存在,可以返回None,或者自己指定的value。
注意:返回None
的时候Python的交互式命令行不显示结果。
要删除一个key,用pop(key)
方法,对应的value也会从dict中删除。
和list比较,dict有以下几个特点:
- 查找和插入的速度极快,不会随着key的增加而变慢;
- 需要占用大量的内存,内存浪费多。
而list相反:
- 查找和插入的时间随着元素的增加而增加;
- 占用空间小,浪费内存很少。
dict的key必须是不可变对象
这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。
要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key。
set
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。
要创建一个set,需要提供一个list作为输入集合:
>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}
注意,传入的参数[1, 2, 3]
是一个list,而显示的{1, 2, 3}
只是告诉你这个set内部有1,2,3这3个元素,显示的顺序也不表示set是有序的。。
重复元素在set中自动被过滤。
通过add(key)
方法可以添加元素到set中,可以重复添加,但不会有效果。
通过remove(key)
方法可以删除元素。
set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}
set和dict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”。
使用key-value存储结构的dict在Python中非常有用,选择不可变对象作为key很重要,最常用的key是字符串。
tuple虽然是不变对象,但试试把(1, 2, 3)
和(1, [2, 3])
放入dict或set中,并解释结果。
函数
在Python中,定义一个函数要使用def
语句,依次写出函数名、括号、括号中的参数和冒号:
,然后,在缩进块中编写函数体,函数的返回值用return
语句返回。
我们以自定义一个求绝对值的my_abs
函数为例:
def my_abs(x):
if x >= 0:
return x
else:
return -x
如果没有return
语句,函数执行完毕后也会返回结果,只是结果为None
。
return None
可以简写为return
。
空函数
如果想定义一个什么事也不做的空函数,可以用pass
语句:
def nop():
pass
pass
语句什么都不做,那有什么用?实际上pass
可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass
,让代码能运行起来。
pass
还可以用在其他语句里,比如:
if age >= 18:
pass
缺少了pass
,代码运行就会有语法错误。
定义函数时,需要确定函数名和参数个数;
如果有必要,可以先对参数的数据类型做检查;
函数体内部可以用return
随时返回函数结果;
函数执行完毕也没有return
语句时,自动return None
。
函数可以同时返回多个值,但其实就是一个tuple。
可变参数
定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*
号。在函数内部,参数numbers
接收到的是一个tuple,因此,函数代码完全不变。
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
允许在list或tuple前面加一个*
号,把list或tuple的元素变成可变参数传进去:
>>> nums = [1, 2, 3]
>>> calc(*nums)
14
关键字参数
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。请看示例
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
命名关键字参数
函数的调用者可以传入任意不受限制的关键字参数
参数组合
Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
Python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。
默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
要注意定义可变参数和关键字参数的语法:
*args
是可变参数,args接收的是一个tuple;
**kw
是关键字参数,kw接收的是一个dict。
以及调用函数时如何传入可变参数和关键字参数的语法:
可变参数既可以直接传入:func(1, 2, 3)
,又可以先组装list或tuple,再通过*args
传入:func(*(1, 2, 3))
;
关键字参数既可以直接传入:func(a=1, b=2)
,又可以先组装dict,再通过**kw
传入:func(**{'a': 1, 'b': 2})
。
使用*args
和**kw
是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。
命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。
定义命名的关键字参数在没有可变参数的情况下不要忘了写分隔符*
,否则定义的将是位置参数。
递归函数
使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。
针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环。
Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。