输入输出
name = raw_input('please enter your name:')
print 'hello', name
控制台输出
C:\Workspace> python hello.py
please enter your name: Michael
hello, Michael
用’’‘表示多行 ,也可以用 \n换行
print ‘’‘line1
line2
line3’’’
字母和对应的数字相互转换:
>>> ord('A')
65
>>> chr(65)
'A'
Python在后来添加了对Unicode的支持,以Unicode表示的字符串用u’…'表示,比如:
>>> print u'中文'
中文
>>> u'中'
u'\u4e2d'
把u’xxx’转换为UTF-8编码的’xxx’用encode(‘utf-8’)方法:
>>> u'ABC'.encode('utf-8')
'ABC'
>>> u'中文'.encode('utf-8')
'\xe4\xb8\xad\xe6\x96\x87'
len()函数可以返回字符串的长度:
>>> len(u'ABC')
3
>>> len('ABC')
3
>>> len(u'中文')
2
>>> len('\xe4\xb8\xad\xe6\x96\x87')
6
把UTF-8编码表示的字符串’xxx’转换为Unicode字符串u’xxx’用decode(‘utf-8’)方法:
>>> 'abc'.decode('utf-8')
u'abc'
>>> '\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
u'\u4e2d\u6587'
>>> print '\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
中文
格式化输出时用%
%d 整数 %f浮点数 %s字符串 %x十六进制整数
>>> 'Hello, %s' % 'world'
'Hello, world'
>>> 'Hi, %s, you have $%d.' % ('Michael', 1000000)
'Hi, Michael, you have $1000000.'
其中,格式化整数和浮点数还可以指定是否补0和整数与小数的位数:
>>> '%2d-%02d' % (3, 1)
' 3-01'
>>> '%.2f' % 3.1415926
'3.14'
在Python 3.x版本中,把’xxx’和u’xxx’统一成Unicode编码,即写不写前缀u都是一样的,而以字节形式表示的字符串则必须加上b前缀:b’xxx’。
list 和 tuple
只有1个元素的tuple定义时必须加一个逗号,,来消除歧义:
>>> t = (1,)
Python在显示只有1个元素的tuple时,也会加一个逗号,,以免你误解成数学计算意义上的括号。
tuple的元素不可变,但可以在tuple里面定义list,修改list值后,由于tuple内对于list的指向不变,所以也不会出错。
条件判断和循环
age = 20
if age >= 18:
print 'your age is', age
print 'adult'
if判断条件还可以简写,比如写(非零字符,非空字符串,非空 list就为真):
if x:
print 'True'
for … in 打印 list 或 tuple
names = ['Michael', 'Bob', 'Tracy']
for name in names:
print name
for x in …循环就是把每个元素代入变量x,然后执行缩进块的语句。
sum = 0
for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
sum = sum + x
print sum
限制循环次数 作为 终止循环的 条件
sum = 0
for x in range(101):
sum = sum + x
print sum
从raw_input()读取的内容永远以字符串的形式返回
birth = int(raw_input('birth: '))
dict和 set
用Python写一个dict如下:
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d['Michael']
95
把数据放入dict的方法,除了初始化时指定外,还可以通过key放入:
>>> d['Adam'] = 67
>>> d['Adam']
67
通过in判断key是否存在:
>>> 'Thomas' in d
False
通过dict提供的get方法,如果key不存在,可以返回None,或者自己指定的value:
>>>d.get('thomas')
>>>d.get('thomas', -1)
-1
注意:返回None的时候Python的交互式命令行不显示结果。
和list 相比 ,dict有以下 几个特点:
1.查找 和插入 的 速度极快,不会随着key的增加 而增加;
2.需要 占用大量的内存,内存浪费多 。
而 list 相反 :
1.查找和 插入时间随着元素的增加而增加;
2.占用空间小,浪费内存很少。
dict是在用空间换时间。
dict的key必须是不可变对象。
dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。
set也是一组key的集合,但不存储value,且没有重复的key,重复元素在 key中自动被过滤。
要创建一个set,需要提供一个list作为输入集合(传入的参数[1, 2, 3]是一个list,而显示的set([1, 2, 3])只是告诉你这个set内部有1,2,3这3个元素,显示的[]不表示这是一个list。):
>>> s = set([1, 2, 3])
>>> s
set([1, 2, 3])
add(key)方法可以添加元素到set中
>>> s.add(4)
>>> s
set([1, 2, 3, 4])
remove(key)方法可以删除元素:
>>> s.remove(4)
>>> s
set([1, 2, 3])
两个set可以做 数学意义上的交集、并集等操作:
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
set([2, 3])
>>> s1 | s2
set([1, 2, 3, 4])
set内部同样必须是不可变对象
函数
help(XXX)查看xxx的函数帮助信息。
比较函数cmp(x, y)就需要两个参数,如果x<y,返回-1,如果x==y,返回0,如果x>y,返回1。
强类型转换与c一致。
函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”:
>>> a = abs # 变量a指向abs函数
>>> a(-1) # 所以也可以通过a调用abs函数
1
如果想定义一个什么事也不做的空函数,可以用pass语句:
def nop():
pass
pass是个占位符,无意义。
例:my_abs对参数类型做检查,只允许整数和浮点类型的参数
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
函数看起来return多个值,其实return的是一个tuple
可以 设置默认参数,如下所示,默认 求 平方
def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。
定义默认参数要牢记一点:默认参数必须指向不变对象!
def add_end(L=None):
if L is None:
L = []
L.append('END')
return L
把函数的参数改为可变参数,在函数调用是自动组装成一个tuple:
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
用可变参数在调用的时候就不用先组装一个list或者tuple 了,像下面这样
>>> calc([1, 2, 3])
14
>>> calc((1, 3, 5, 7))
84
只用这样调用即可 ,几个参数都行
>>> calc(1, 2)
5
>>> calc()
0
或者用已有的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
和可变参数类似,也可以先组装出一个dict,然后,把该dict转换为关键字参数传进去:
>>> kw = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, city=kw['city'], job=kw['job'])
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
当然,上面复杂的调用可以用简化的写法:
>>> kw = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **kw)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数。
例:
def func(a, b, c=0, *args, **kw):
print 'a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw
调用:
```bash
func(1,2)
a = 1 b = 2 c = 0 args = () kw = {}
func(1, 2, c = 3)
a = 1 b = 2 c = 3 args = () kw = {}
func(1, 2, 3, 'a', 'b')
a = 1 b = 2c = 3 args = ('a', 'b') kw = {}
func(1, 2, 3, 'a', 'b', x = 99)
a = 1 b = 2 c = 3 args = (‘a’, 'b') kw = {'x':99}
通过一个tuple和 dict,可以直接调用
```bash
args = (1, 2, 3, 4)
kw = {'x':99}
func(*args, **kw)
a = 1 b = 2 c = 3 args = (4,) kw = {'x':99}
即对于任意函数都可以通过func(*args, **kw)的 形式调用它
递归函数
递归调用通过栈来实现,但调用层数过多会导致栈溢出,解决这一问题的方法是尾递归优化
原本是:
def fact(n)
if n = 1:
return 1
return n * fact(n-1)
优化为:
尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。
def fact(n)
return fact_iter(n,1) #调用函数
def fact_iter(num, product):
if num == 1:
return product
return fact_iter(num -1, num * product)
尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导致栈溢出。
遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出。
切片
list
L[0:3] #前三个元素
L[1:3] #也可以从索引1开始,取出2个元素出来
L[-2:] #倒数两个 元素
L[-2:-1] #倒数 第二个元素
L[:10] #前十个 元素
L[10:20] #十一到 20个数
L[:10:2] #前十个数每两个 取一个
L[::5] #所有数每五个取一个
L[:] #原样输出
(0, 1, 2, 3, 4, 5)[:3] #tuple前三个元素
'ABCDEFG'[:3] #字符串前三个
'ABCDEFG'[::2] #字符串每隔两个输出一个
迭代
for … in
dict: for key in d: print(key)
字符串: for ch in 'abc': print (ch)
用collections模块的iterable判断是否是可迭代对象。
例:
form collection import iterable
isinstance('abc', iterable) #看str是否可迭代
true
isinstance([1, 2, 3], iterable) #list是否可迭代
true
isinstance(123, iterable) #整数是否可迭代
false
python内置的enumerate函数可以把一个list变成索引元素对,这样可以在for循环中同时迭代索引和元素本身:
for i, value in enumerate([‘a’, ‘b’, 'c]):
print(i, value)
同时引用两个变量很常见 ,如下
for x, y in[(1, 1), (2, 4), (3, 9)]:
print(x, y)
请使用迭代查找一个list中最小和最大值,并返回一个tuple:
if L:
max = L[0]
min = L[0]
for t in L:
if t > max:
max = t
if t < min:
min = t
return (max, min)
else:
return (None,None)
列表生成器
列表生成器即 list comprehensions,是python内置的简单而枪法的创建list的生成式。
>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
生成[1x1, 2x2, 3x3, …, 10x10]
>>> L = []
>>> for x in range(1, 11):
... L.append(x * x)
...
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
简化
>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
加if判断
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
使用两层循环,生成全排列
>>>[m + n for m in 'abc' for n in 'xyz']
>['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
列出当前目录下的所有文件和目录名
>>> import os #导入OS模块
>>>[d for d in os.listdir(' . ')]
>['.emacs.d', '.ssh', '.Trash', 'Adlm', 'Applications', 'Desktop', 'Documents', 'Downloads', 'Library', 'Movies', 'Music', 'Pictures', 'Public', 'VirtualBox VMs', 'Workspace', 'XCode']
for循环可以同时两个或多个变量,比如dict的item()可以同时迭代key和value:
>>>d = {'x': 'A', 'y': 'B', 'z':'C'}
>>>for k, v in d.items();
>>> print(k, '=', v)
y = B
x = A
z = C
列表生成式也可以使用两个变量生成list:
>>> d = {'x':'A', 'y':'B', 'z':'C'}
>>>[k + '=' + v for k, v in d.items()]
>['y=B', 'x=A', 'z=C']
为什么s.lower() for s in L要写在 中括号里面
最后把一个list中所有的字符串变成小写 :
>>>L = ['Hello', 'World', 'IBM', 'Apple']
>>>[s.lower() for s in L]
['hello', 'world', 'ibm', 'apple']
if 。。。 else
for后可加if作为条件判断或者说 筛选条件,不能加else
例: x for x in range(1, 11) if x % 2 == 0]
在for 之前加if的话必须加else,因为 是表达式
例:x if x % 2 == 0 else -x for x in range(1, 11)
练习,如果list中既包含字符串,又包含正式 ,非字符串没有lower()的方法,列表生成式会报错
L = [‘Hello’, ‘World’, 18, ‘Apple’,None]
[s.lower() for s in L]
使用内建的函数isinstance可以判断一个变量是不是字符串
x = ‘abc’
y = 123
isinstance(x, str)
ture
isinstance(y, str)
false
# -*- coding:utf-8 -*-
L1 = ['Hello', 'World', 18. 'Apple', None]
L2 = list()
for x in L1:
if isinstance(x, str):
L2.append(x.lower())