zoukankan      html  css  js  c++  java
  • 廖大大python学习笔记1

    列表
    classmates = ['Michael', 'Bob', 'Tracy']
    classmates.append('tom')
    print classmates
    # classmates.insert(7,'tom1')
    classmates.pop(0)
    classmates[0]='mark'
    print classmates

    >>> p = ['asp', 'php']
    >>> s = ['python', 'java', p, 'scheme']
    要拿到'php'可以写p[1]或者s[2][1],因此s可以看成是一个二维数组,类似的还有三维、四维……数组,


    元组
    现在,classmates这个tuple不能变了,它也没有append(),insert()这样的方法。其他获取元素的方法和list是一样的,你可以正常地使用classmates[0],classmates[-1],但不能赋值成另外的元素。
    不可变的tuple有什么意义?因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple。
    只有1个元素的tuple定义时必须加一个逗号,,来消除歧义:
    >>> t = (1,)
    >>> t
    (1,)


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

    if语句执行有个特点,它是从上往下判断,如果在某个判断上是True,把该判断对应的语句执行后,就忽略掉剩下的elif和else
    if判断条件还可以简写,比如写:
    if x:
    print 'True'
    只要x是非零数值、非空字符串、非空list等,就判断为True,否则为False。
    从raw_input()读取的内容永远以字符串的形式返回,把字符串和整数比较就不会得到期待的结果,必须先用int()把字符串转换为我们想要的整型

    字典
    要避免key不存在的错误,有两种办法,一是通过in判断key是否存在:
    >>> 'Thomas' in d
    False
    二是通过dict提供的get方法,如果key不存在,可以返回None,或者自己指定的value:
    >>> d.get('Thomas')
    >>> d.get('Thomas', -1)
    -1
    注意:返回None的时候Python的交互式命令行不显示结果。
    请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。
    和list比较,dict有以下几个特点:
    1. 查找和插入的速度极快,不会随着key的增加而增加;
    2. 需要占用大量的内存,内存浪费多。
    而list相反:
    3. 查找和插入的时间随着元素的增加而增加;
    4. 占用空间小,浪费内存很少。
    所以,dict是用空间来换取时间的一种方法。
    dict可以用在需要高速查找的很多地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是不可变对象。
    这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。
    要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key:

    空函数
    如果想定义一个什么事也不做的空函数,可以用pass语句:
    def nop():
    pass
    pass语句什么都不做,那有什么用?实际上pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来。
    pass还可以用在其他语句里,比如:
    if age >= 18:
    pass
    缺少了pass,代码运行就会有语法错误。
    函数的参数

    Python的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。
    def power(x, n=2):
    s = 1
    while n > 0:
    n = n - 1
    s = s * x
    return s

    从上面的例子可以看出,默认参数可以简化函数的调用。设置默认参数时,有几点要注意:
    一是必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);
    二是如何设置默认参数。
    当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
    使用默认参数有什么好处?最大的好处是能降低调用函数的难度。
    定义默认参数要牢记一点:默认参数必须指向不变对象!

    为什么要设计str、None这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。

    # 定义可变参数,在参数前面加一个*,如果在给定的参数去调用可变参数在给定的参数前面加*,这样变成了可变参数,在调用
    # def calc(*number):
    # sum=0
    # for n in number:
    # sum+=n*n
    # print sum
    # return sum
    #
    # nums=[1,2,3]
    # calc(*nums)

    # # 关键字参数可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。请看示例:
    # def person(name, age, **kw):
    # print 'name:', name, 'age:', age, 'other:', kw
    #
    # # person('jack', 18)
    #
    # # person('jack', 18, city='beijing', gender='M', job='Engineer')
    # # 关键字参数有什么用?它可以扩展函数的功能。比如,在person函数里,我们保证能接收到name和age这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。
    # kw={'city' :'beijing', 'job': 'Engineer'}
    # person('mark', 18,**kw)

    # 参数组合
    '''
    必选参数、默认参数、可变参数和关键字参数,这4种参数都可以一起使用,或者只用其中某些,但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数。
    '''
    def func(a, b, c=0, *args, **kw):
    print 'a=',a, 'b=',b, 'c=',c, 'args=', args, 'kw=', kw
    #在函数调用的时候,Python解释器自动按照参数位置和参数名把对应的参数传进去
    args=(1,2,3,4)
    kw={'x':99}
    func(*args,**kw)
    小结
    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的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。

    递归函数
    在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数
    使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。可以试试fact(1000):

    解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。
    尾递归是指,在函数返回的时候,调用自身本身,并且,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)函数改成尾递归方式,也会导致栈溢出。
    迭代
    所以,当我们使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行,而我们不太关心该对象究竟是list还是其他数据类型。
    那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:
    >>> 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循环中同时迭代索引和元素本身:
    >>> for i, value in enumerate(['A', 'B', 'C']):
    ... print i, value
    ...
    0 A
    1 B
    2 C

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


    列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。
    写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来


    生成器
    通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
    所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。
    要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:
    # g=(x*x for x in xrange(10))
    # for n in g:
    # print n

    #而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
    def fib(max):
    n,a,b=0,0,1
    while n<max:
    yield b
    a,b=b,a+b
    n=n+1
    for n in fib(6):
    print n

  • 相关阅读:
    SQL Server优化(4)-聚集索引的重要性和如何选择聚集索引
    青岛开发区公交集团公交线路一览表
    WINDOWS下文件夹简介
    2008 SQL Server优化(2)-改善SQL语句
    【麦课在线教育mycourse】利用Js快速刷完新生安全教育课程
    Linux重启网卡的方法
    Trees
    计算机操作系统之设备管理
    linux目录结构及主要内容
    Linux mysql命令安装允许远程连接
  • 原文地址:https://www.cnblogs.com/tom-gao/p/7094991.html
Copyright © 2011-2022 走看看