Contents
  1. 1. 基础
  2. 2. 编码(涨姿势)
  3. 3. 列表 list
  4. 4. 元组 tuple
  5. 5. 字典 dict
  6. 6. set
  7. 7. 条件判断
  8. 8. 循环
  9. 9. 函数
  10. 10. 切片
  11. 11. 迭代
  12. 12. 列表生成式
  13. 13. 生成器
  14. 14. 函数式编程

学习廖雪峰的Python 2.7教程的笔记,关注Javaer觉得比较不同和值得记录的地方。

基础

1
2
3
4
5
6
7
8
9
10
11
12
13
print "hello","world"      #中间连空格
raw_input() #输入,以字符串的形式
r"\\\t\\" #用r不转义
'''多行内容,可用于注释'''
True False #布尔值,非零数值、非空字符串、非空list等就判断为True
and or not #逻辑操作
None #空值,返回None的时候Python的交互式命令行不显示结果
'%s,%d' % ('Zhang', 100) #字符串格式化
len('中') #字符数?
int('123')
str(123) #类型转换
a="abc"
a=a.replace("a","A")

Python是动态语言(变量本身类型不固定的语言),常量一般全部大写。

编码(涨姿势)

美国 ASCII、中国 GB2312 => 统一 Unicode => 可变长 UTF-8(相当于UTF-8包含了ASCII)

内存中统一使用Unicode编码。保存到硬盘 或者 传输的时候,就转换为UTF-8编码。

1
2
3
4
5
6
ord('A') 
chr(65) #字符和ASCII转换
u'中' #Unicode字符串
u'中'.encode('utf-8') #Unicode转换为UTF-8
u'中'.encode('gb2312') #Unicode转换为GB2312
'\xe4\xb8\xad'.decode('utf-8') #UTF-8转换为Unicode

Python 2.x版本虽然支持Unicode,但在语法上有’xxx’和u’xxx’两种字符串表示方式。
在Python 3.x版本中,把’xxx’和u’xxx’统一成Unicode编码,即写不写前缀u都是一样的,而以字节形式表示的字符串则必须加上b前缀:b’xxx’。

因此.py的文件头必须加上:

1
2
#!/usr/bin/env python
# -*- coding: utf-8 -*-

第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;

第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。


列表 list

1
2
3
4
5
6
7
8
list=[1,'二',True,[0,9]]    #各种类型都可以
len(list) #长度
list[-1] #索引最后一个元素
list.append('four')
list.pop()
list.insert(2,'insert')
list.pop(2)
list.sort()

元组 tuple

相当于一旦初始化就不能修改的list

1
2
tuple=(1,'二',True,(0,9),[0,9])  #存在数学括号的歧义性
x,y=(1,'二')

字典 dict

就是Java中的map般的存在,键值对

1
2
3
dict = {'Zhang': 95, 'Li': 75, 123: 85}
dict['Wang']=88
dict.pop('Li')

key的对象就不能变,如字符串、整数等
避免key不存在的错误:一是通过in判断key是否存在,二是通过dict提供的get(key)方法

set

这Java中也有,不重复的key,且没有value

1
2
3
s=set([1,1,2,2,3,3])
s.add(1)
s.remove(1)

条件判断

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

else if => elif
{ } => 缩进
还有都要:符号

循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
str='helloworld'

for value in str[::2]: #好用的切片,从头到尾,步长2
print value

for index in range(len(str))[::2]:
print str[index]

for index,value in enumerate(str[::2]):
print index,value
```

在 python 中,`forelse` 表示这样的意思,for 中的语句和普通的没有区别,else 中的语句会在循环正常执行完(即 for 不是通过 break 跳出而中断的)的情况下执行,whileelse 也是一样([W3CSCHOOL - Python for 循环语句][1])。
```python
for i in range(5): #产生[0,1,2,3,4]
print i
if i==5:
break
else:
print "no break"

pass是空语句,是为了保持程序结构的完整性。


函数

参数顺序为必选参数 > 默认参数 > 可变参数 > 关键字参数

默认参数,必须指向不变对象,不能是List。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def my_abs(x=0):
if not isinstance(x, (int, float)): # 类型检查
raise TypeError('bad operand type')
if x >= 0:
return x,'正'
else:
return -x,'负' #返回tuple
```


可变参数,在函数调用时自动组装为一个tuple。
```python
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum

>>> calc(1, 2)
>>> nums = [1, 2, 3]
>>> calc(*nums)

关键字参数,允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。

1
2
3
4
5
6
7
8
9
10
def func(a, b, c=0, *args, **kw):
print 'a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw

>>> func(1, 2, 3, 'a', 'b', x=99)
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}

>>> 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)的形式调用它,无论它的参数是如何定义的”的修改意见:定义时含有可变参数和关键字参数的函数,才可以通过类似func(args, **kw)的形式调用它。如果

1
2
def func(a,b,c=0):
# 略

并不能通过func(args, **kw)调用。
实际上,`func(
args, **kw)`是函数的通用形式。


切片

可对list、tuple、字符串进行切片。

1
2
3
4
list=[1,'二',True,[0,9]]
list[::2] #步长为2
range(100)[:10:2]
'abcdefg'[:3]

迭代

只要是可迭代对象,无论有无下标,都可以迭代,比如dict就可以迭代。

1
2
from collections import Iterable
isinstance('abc', Iterable) # 判断str是否可迭代

1
2
for x, y in [(1, 1), (2, 4), (3, 9)]:
print x, y

列表生成式

即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

1
2
3
L=[str(k)+'='+str(v) for k,v in {"Zhang":95,123:66}.iteritems()] #注意不要声明和内置方法同名的变量或方法,比如str="123",就会导致str(123)不能用
L=[x*y for x in range(1,4) for y in range(1,5) if x+y>5] #列表生成式
L=[x*y if x+y>5 else 0 for x in range(1,4) for y in range(1,5)] #列表生成式还可带条件

1
2
3
L =['Hello', 'World', 18, 'Apple', None]                             #将是str类型转换为小写,且保留非str
L= [s.lower() if isinstance(s,str) else s for s in L] #方法一
L= [s.lower() for s in L if isinstance(s,str) else s for s in L] #方法二

补充:留言有关于列表生成式和条件表达式的讨论,个人观点

列表生成式

1
2
3
4
comprehension ::=  expression comp_for
comp_for ::= "for" target_list "in" or_test [comp_iter]
comp_iter ::= comp_for | comp_if
comp_if ::= "if" expression_nocond [comp_iter]

条件表达式

1
2
3
conditional_expression ::=  or_test ["if" or_test "else" expression]
expression ::= conditional_expression | lambda_expr
expression_nocond ::= or_test | lambda_expr_nocond

注意到

  • 条件表达式 | lambda表达式 + for 是列表生成式的一种形式
  • 条件表达式没有for
  • 列表生成式中的comp_if::= "if" expression_nocond [comp_iter]有for,但并不是条件表达式

所以方法一中的s.lower() if isinstance(s,str) else s是条件表达式,这是列表生成器。而方法二中的s.lower() for s in L if isinstance(s,str) else s不是条件表达式,if isinstance(s,str) else s for s in L也不是条件表达式而符合列表生成器的comp_if ::= "if" expression_nocond [comp_iter],所以也是列表生成器。

生成器

一边循环一边计算的机制,节省内存。可用()和关键字yield声明。

1
2
g = (x * x for x in range(10))
g.next() #也可迭代

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b #生成器的关键字
a, b = b, a + b
n = n + 1

f=fib(6)
f.next() #输出1

for n in f
print n #输出1 2 3 5 8,跳过了第一个1

for n in fib(6) #这是一个新的生成器
print n #输出1 1 2 3 5 8

在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。


函数式编程

一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量(内部)。Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。
变量可以指向函数f=str(),函数名也是变量str=123

函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数。高阶函数可以接受函数作为参数外,还可以把函数作为结果值返回。

  • 传入函数

接受一个函数和一个序列的函数包括

1
2
3
4
map(f, [x1, x2, x3, x4])     #相当于[f(x1),f(x2),f(x3),f(x4)]
reduce(f, [x1, x2, x3, x4]) #相当于f(f(f(x1,x2),x3),x4)
filter(f, [x1, x2, x3, x4]) #如果f(x1)为True,则保留,否则丢弃
sorted([x1, x2, x3, x4],f) #可根据f返回的1、0、-1排序

以实现类型转换函数int()为例:

1
2
3
4
def str2int(s):
def char2num(s):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
return reduce(lambda x,y: x*10+y, map(char2num, s))

函数内可以定义函数,内部函数可以引用外部函数的参数和局部变量。

  • 返回函数

相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。每次调用都会返回一个新的函数。

p.s. 闭包的知识略微复杂,为此专门另写了一篇博客《闭包的概念、例子和作用》
p.p.s 由于Python2的bug,廖博客中的代码实际需要修改,可见python中的闭包一文,详细的探究过程来自Python的闭包研究一文。

Contents
  1. 1. 基础
  2. 2. 编码(涨姿势)
  3. 3. 列表 list
  4. 4. 元组 tuple
  5. 5. 字典 dict
  6. 6. set
  7. 7. 条件判断
  8. 8. 循环
  9. 9. 函数
  10. 10. 切片
  11. 11. 迭代
  12. 12. 列表生成式
  13. 13. 生成器
  14. 14. 函数式编程