python学习笔记:1.基础

对于大多数程序员来说,有了一定功底,就会觉得语言大同小异,再学习动态语言,也不会觉得是难事。因此,我只做一些简单的记录,记录会跟静态语言混淆的地方。

数据类型,变量

  • python中同一个变量,可以反复赋值,而且可以是不同类型的变量。这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错,笔记java.

    1
    2
    3
    4
    a = 123 # a是整数
    print a
    a = 'ABC' # a变为字符串
    print a
  • 通常用全部大写,表示常量。Python根本没有任何机制保证PI不会被改变,所以,用全部大写的变量名表示常量只是一个习惯上的用法

list

  • Python内置的一种数据类型是列表:list。list是一种有序的集合,可以随时添加和删除其中的元素
    用索引来访问list中每一个位置的元素,记得索引是从0开始的,这点跟lua有区别

    1
    2
    3
    nameList = ['xiaoming','xiaoli','xiaozhang']
    print nameList
    print len(nameList)
  • 如果要取最后一个元素,除了计算索引位置外,还可以用-1做索引,直接获取最后一个元素,以此类推,可以获取倒数第2个、倒数第3个:

    1
    2
    nameList[-1]
    nameList[-2]
  • 要删除list末尾的元素,用pop()方法

  • 要删除指定位置的元素,用pop(i)方法,其中i是索引位置

tuple

元组,跟list的区别是,元组是不能修改的,不能赋值成其他的元素,

1
nameList = ('xiaoming','xiaoli','xiaozhang')

dic

字典,普遍用法

  • 判断key是否存在

    1
    2
    3
    'key' in dict
    或者
    dict.get('key')
  • 删除key:pop(key)

set

set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。
s = set([1, 2, 3])

  • 重复元素在set中自动被过滤:

    1
    2
    3
    >>> s = set([1, 1, 2, 2, 3, 3])
    >>> s
    set([1, 2, 3])
  • 通过add(key)方法可以添加元素到set中,可以重复添加,但不会有效果

  • 通过remove(key)方法可以删除元素:

  • set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:
    1
    2
    3
    4
    5
    6
    >>> s1 = set([1, 2, 3])
    >>> s2 = set([2, 3, 4])
    >>> s1 & s2
    set([2, 3])
    >>> s1 | s2
    set([1, 2, 3, 4])

字符编码

  • 支持中文,需要在开头添加
1
# -*- coding: utf-8 -*-
  • 在Python中,采用的格式化方式和C语言是一致的,用%实现,举例如下:
1
2
3
4
5
6
7
8
9
a = 'Hi ,%s,you have 钱数:%d' % ('Hammercui',10000)
print a

常见的占位符有:

%d 整数
%f 浮点数
%s 字符串
%x 十六进制整数

函数

  • abs()绝对值函数
  • cmp(x,y)比较函数
  • int() 转int函数
  • 声明函数:def,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。
1
2
3
4
5
6
7
def my_abs(x):
if x>0:
return x
else:
return -x

print my_abs(-2000)
  • 默认参数
1
2
3
4
5
6
7
8
def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s

power(5)
  • fact(n)阶乘函数。递归不做优化的话,会导致栈溢出

slice切片操作符

L[0:3]表示从list L中取出索引0到3,不包括3的元素,返回list
前10个数,每两个取一个:

1
2
 L[:10:2]
[0, 2, 4, 6, 8]

  • 字符串’xxx’或Unicode字符串u’xxx’也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串:
1
2
3
4
>>> 'ABCDEFG'[:3]
'ABC'
>>> 'ABCDEFG'[::2]
'ACEG'

迭代

  • 判断是否能是迭代

    1
    2
    3
    4
    5
    6
    7
    >>> from collections import Iterable
    >>> isinstance('abc', Iterable) # str是否可迭代
    True
    >>> isinstance([1,2,3], Iterable) # list是否可迭代
    True
    >>> isinstance(123, Iterable) # 整数是否可迭代
    False
  • 如果要对list实现类似Java那样的下标循环怎么办?Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:

    1
    2
    3
    # 模仿java写法
    for i,value in enumerate(['a','b','c']):
    print i,value

列表生成式

但如果要生成[1x1, 2x2, 3x3, …, 10x10]怎么做?方法一是循环,方法二如下:

1
2
>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

可以增加条件

1
2
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]

还可以双层循环

1
2
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

生成器generator

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)

定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator

而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。这样就保证了,每次next都是从上次的结果之后执行的。

高阶函数

指函数名也是变量,可以把函数作为参数传递。
把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式

map函数

接收两个参数,第一个函数,第二个序列(可以是list,tuple),返回结果list
比如,把一个int类型的list转成string类型的list

1
2
3
map(str,[1,2,3,4])
结果:
['1','2','3','4']

reduce函数

接收两个参数,第一函数,但这个函数必须接收2个参数,第二个序列,返回list。
reduce与map的区别是

1
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

相当于每次传入2个参数,把结果作为新的参数,跟下一个参数再传入

filter函数

传入两个参数,和map()不同的时,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

例如,在一个list中,删掉偶数,只保留奇数,可以这么写:

1
2
3
4
5
6
def is_odd(n):
return n % 2 == 1

filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])
结果
# 结果: [1, 5, 9, 15]

sorted函数

与其他相反,序列在前,函数在后

匿名函数

比如函数

1
2
def f(x)
return x*x

可以写作
lambda x:x*x
用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数

装饰器

假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。

偏函数

当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。

比如二进制转换成int

1
2
3
4
5
6
def int2(x, base=2):
return int(x, base)

int2('1000000')
结果
64

使用偏函数写法就是

1
2
3
4
5
import functools
int2 = functools.partical(int,base=2)
int2('1000000')
结果
64