python学习笔记(2)

37、列表
(1)添加新的元素,注意不能使用+号来添加元素,+号的使用级别是列表,即两个操作数都是列表的情况下才可以连接:

>>> s=[1,2,3,4]
>>> s.append(5)
>>> s
[1, 2, 3, 4, 5]
>>> 

(2)序列类型函数
sorted() and reversed():
sorted()只是对s进行排序,并没有改变s的真实顺序
>>>s=[4,5,43,2,543,2,432,64]
>>> sorted(s)
[2, 2, 4, 5, 43, 64, 432, 543]
>>> sum(s)  #求和
1095

(3)list()和tuple()
list()函数和tuple()函数接受可迭代对象(比如另一个序列)作为参数,并通过浅拷贝数据来创建一个新的列表或者元组。更多的情况下,它们用于在两种类型之间进行转换
(4)sort()/reverse()和sorted()/reversed()的区别
sort()/reverse()会在原地操作,没有返回值,是通过对象的点调用的,对象被改变
sorted()/reversed()相当于表达式,将一个对象排序之后生成一个新的对象,原来的对象并不改变,返回这个新的对象


38、元组
(1)元组是一种不可变类型.正因为这个原因,元组能做一些列表不能做的事情... 用做一个字典的key.另外当处理一组对象时,这个组默认是元组类型.

元组不可变也是有一定的限度的,若是元组中含有可变的元素,那么在这个层面上这个元组也是可以改变的,如:

>>> atuple=(['xyz',123],'abc',456)
>>> atuple
(['xyz', 123], 'abc', 456)
>>> atuple[0][1]
123
>>> atuple[0][1]='opq'
>>> atuple
(['xyz', 'opq'], 'abc', 456)
>>> 

(2)默认集合类型
所有的多对象的,逗号分隔的,没有明确用符号定义的,等等这些集合默认的类型都是元组,所有函数返回的多对象(不包括有符号封装的)都是元组类型。

>>> def foo():
	return 1,2,3

>>> foo()
(1, 2, 3)

但不推荐这么做,还是显示定义的比较好

(3)单元素元组
由圆括号包裹的一个单一元素首先被作为分组操作,而不是作为元组的分界符。一个变通的方法是在第一个元素后面添一个逗号(,)来表明这是一个元组而不是在做分组操作.

>>> ('xyz')
'xyz'
>>> ('xyz',)
('xyz',)
>>> 

(4)深拷贝和浅拷贝
我觉得《核心编程》上关于深拷贝和浅拷贝的说法有一些错误:p241

首先,对象拷贝不是简单的把对象的引用赋值给另外一个变量,这样不是拷贝,拷贝分为浅拷贝和深拷贝,不管是哪种拷贝,在最初都会生成一个新的对象,虽然对象中有可能会存在引用到源对象。

其次,序列类型对象的浅拷贝是默认类型拷贝,并可以以下几种方式实施:(1)完全切片操作[:],(2)
利用工厂函数,比如list(),dict()等,(3)使用copy 模块的copy 函数.

深拷贝通过copy模块的deepcopy()函数来实现,深拷贝的是列表元素,元组元素不进行深拷贝

以下有几点关于拷贝操作的警告。第一,非容器类型(比如数字,字符串和其他"原子"类型的
对象,像代码,类型和xrange 对象等)没有被拷贝一说,浅拷贝是用完全切片操作来完成的.第二,
如果元组变量只包含原子类型对象,对它的深拷贝将不会进行。

深拷贝示例:
>>> person=['name',['savings',100.00]]
>>> import copy
>>> hubby=copy.deepcopy(person)
>>> wifey=copy.deepcopy(person)
>>> [id(x) for x in person]
[22135968, 27744536]
>>> [id(x) for x in hubby]
[22135968, 32582712]
>>> [id(x) for x in wifey]
[22135968, 32582952]
>>> hubby[0]='suo'
>>> wifey[0]='piao'
>>> person,hubby,wifey
(['name', ['savings', 100.0]], ['suo', ['savings', 100.0]], ['piao', ['savings', 100.0]])
>>> hubby[1][1]=50.00
>>> person,hubby,wifey
(['name', ['savings', 100.0]], ['suo', ['savings', 50.0]], ['piao', ['savings', 100.0]])
>>> 



注意:进行拷贝的时候,一定要考虑到各种引用,不能想当然怎么样就怎么样


39、字典

键值对、映射类型

keys():返回字典中所有的键,以列表形式
values():返回字典中所有的值,以列表形式
items():返回字典中所有的元素,返回类型为以键值对组成的元组为元素的列表
has_key(key):判断字典中是否存在key这个键,返回布尔值,类似的可以使用in或者是not in来判断

字典中的键是不可以改变的,所以数字和字符串可以作为字典中的键,但是列表和其他字典则不行。

不允许一个键对应多个值,键必须是可以哈希的

字典可以和所有的标准类型操作符一起工作,但却不支持像拼接(concatenation)和重复(repetition)这样的操作。这些操作对序列有意义,可对映射类型行不通。

(1)增加新元素,如下:
>>> dict2={x:'15364072939','piao':'18946799512'}
>>> dict2['dai']='15200859293'
>>> dict2
{'suo': '15364072939', 'piao': '18946799512', 'dai': '15200859293'}


(2)映射类型的相关函数
dict([container]): 创建字典的工厂函数。如果提供了容器类(container) , 就用其中的条目填充字典,否则就创建一个空字典。
len(mapping): 返回映射的长度(键-值对的个数)
hash(obj): 返回obj 的哈希值


(3)字典类型方法
dict.clear() 删除字典中所有元素
dict.copy() 返回字典(浅复制)的一个副本
dict.fromkeys(seq,val=None): 创建并返回一个新字典,以seq 中的元素做该字典的键,val 做该字
典中所有键对应的初始值(如果不提供此值,则默认为None)
dict.get(key,default=None) 对字典dict 中的键key,返回它对应的值value,如果字典中不存在此
键,则返回default 的值(注意,参数default 的默认值为None)
dict.has_key(key) 如果键(key)在字典中存在,返回True,否则返回False. 在Python2.2
版本引入in 和not in 后,此方法几乎已废弃不用了,但仍提供一个可工作的接口。
dict.items() 返回一个包含字典中(键, 值)对元组的列表
dict.keys() 返回一个包含字典中键的列表
dict.iter() 方法iteritems(), iterkeys(), itervalues()与它们对应的非迭代方法一样,不同的是它们返回一个迭代子,而不是一个列表。
dict.pop(key[, default]) 和方法get()相似,如果字典中key 键存在,删除并返回dict[key],
如果key 键不存在,且没有给出default 的值,引发KeyError 异常。
dict.setdefault(key,default=None) 和方法set()相似,如果字典中不存在key 键,由dict[key]=default 为它赋值。
dict.update(dict2) 将字典dict2 的键-值对添加到字典dict
dict.values() 返回一个包含字典中所有值的列表

iteritems(), iterkeys(), 和itervalues()
这些函数与返回列表的对应方法相似,只是它们返回惰性赋值的迭代器,所以节省内存。数据集如果很大会导致很难处理。

40、集合
集合(sets)有两种不同的类型,可变集合(set) 和 不可变集合(frozenset)。可变
集合(set)不是可哈希的,因此既不能用做字典的键也不能做其他集合中的元素。不可变集合
(frozenset)则正好相反,即,他们有哈希值,能被用做字典的键或是作为集合中的一个成员。


(1)集合没有特定的语法格式,只能使用工厂方法set()、frozenset()来创建集合

set()和frozenset()工厂函数分别用来生成可变和不可变的集合。如果不提供任何参数,默认
会生成空集合。如果提供一个参数,则该参数必须是可迭代的,即,一个序列,或迭代器,或支持
迭代的一个对象,例如:一个文件或一个字典。

>>>s=set('suoo')
s
>>> s
set(['s', 'u', 'o'])
>>> s=frozenset('piaodatou')
>>> s
frozenset(['a', 'd', 'i', 'o', 'p', 'u', 't'])

(2)遍历集合
>>>for i in s:
	print i,

a d i o p u t

(3)更新集合
用各种集合内建的方法和操作符添加和删除集合的成员,注意:只有可变集合可以被修改
>>> s=set('piaodatou')
>>> s
set(['a', 'd', 'i', 'o', 'p', 'u', 't'])
>>> s.add('z')
>>> s.add('xyz')
>>> s
set(['a', 'd', 'i', 'xyz', 'o', 'p', 'u', 't', 'z'])
>>> s.update('gh')
>>> s
set(['a', 'd', 'g', 'i', 'h', 'xyz', 'o', 'p', 'u', 't', 'z'])
>>> s-=set('gh')
>>> s
set(['a', 'd', 'i', 'xyz', 'o', 'p', 'u', 't', 'z'])

(4)集合等价与不等价
等价/不等价被用于在相同或不同的集合之间做比较。两个集合相等是指,对每个集合而言,当
且仅当其中一个集合中的每个成员同时也是另一个集合中的成员。
你也可以说每个集合必须是另一个集合的一个子集, 即,s <= t 和 s >= t 的值均为真(True),
或(s <= t and s>= t) 的值为真(True)。集合等价/不等价与集合的类型或集合成员的顺序无关,
只与集合的元素有关。

这与数学中的集合的概念非常类似


(5)集合的交、并、补、对称差分(适用于所有的集合类型,可变和不可变的)
>>> s=set('suo')
>>> t=set('piao')
>>> s
set(['s', 'u', 'o'])
>>> t
set(['i', 'p', 'a', 'o'])
>>> s|t     #并集
set(['a', 'p', 's', 'u', 'i', 'o'])
>>> s&t     #交集
set(['o'])
>>> s-t     #差集
set(['s', 'u'])
>>> t-s     #差集
set(['i', 'p', 'a'])
>>> s^t     #对称差分
set(['a', 'i', 'p', 's', 'u'])

如果左右两个操作数的类型相同,既都是可变集合或不可变集合, 则所产生的结果类型是相同
的,但如果左右两个操作数的类型不相同(左操作数是set,右操作数是frozenset,或相反情况),则所产生的结果类型与左操作数的类型相同

(6)只适用于可变集合的类型操作符
s|=t   s&=t    s-=t   s^=t

(7)集合类型内建方法
适用于所有的集合类型:
s.issubset(t) 如果s 是t 的子集,则返回True,否则返回False
s.issuperset(t) 如果t 是s 的超集,则返回True,否则返回False
s.union(t) 返回一个新集合,该集合是s 和t 的并集
s.intersection(t) 返回一个新集合,该集合是s 和t 的交集
s.difference(t) 返回一个新集合,该集合是s 的成员,但不是t 的成员
s.symmetric_difference(t) 返回一个新集合,该集合是s 或t 的成员,但不是s 和t 共有的
成员
s.copy() 返回一个新集合,它是集合s 的浅复制

适用于可变集合:
add(), remove(), discard(), pop(), clear().


(8)集合模块


41、条件和循环
(1)条件表达式,即三元操作符
>>> x=4
>>> y=8
>>> smaller=x if x<y else y
>>> smaller
4

(2)与序列相关的内建函数
sorted(), reversed(), enumerate(), zip()
其中两个函数( sorted() 和 zip() )返回一个序列(列表), 而另外两个函数( reversed() 和 enumerate() )返回迭代器(类似序列)

(3)continue
continue 语句并不是"立即启动循环的下一次迭代". 实际上, 当遇到continue 语句时, 程
序会终止当前循环,并忽略剩余的语句, 然后回到循环的顶端. 在开始下一次迭代前,如果是条件循
环, 我们将验证条件表达式.如果是迭代循环,我们将验证是否还有元素可以迭代. 只有在验证成功
的情况下, 我们才会开始下一次迭代.

(4)pass
不做任何事情,类似c语言中的空的大括号

(5)while-else和for-else

# -*- coding: cp936 -*-
#求一个数的最大约数,练习使用while-else语句
#当循环全部正常执行完毕之后,才会执行else中的语句,break也算是非正常结束循环
def showMaxFactor(num):
    count=num/2
    while count>1:
        if num%count==0:
            print 'largest factor of %d is %d' % (num,count)
            break
        count-=1
    else:
        print num,'is prime'

for eachNum in range(10,21):
    showMaxFactor(eachNum)

(6)迭代器
迭代器就是有一个 next() 方法的对象, 而不是通过索引来计数. 当你或是一个循环机制(例如 for 语句)需要下一个项时, 调用迭代器的 next() 方法就可以获得它. 条目全部取出后, 会引发一个StopIteration 异常, 这并不表示错误发生, 只是告诉外部调用者, 迭代完成。如下:

>>> s=(123,'suo',56.78)
>>> s
(123, 'suo', 56.78)
>>> i=iter(s)
>>> i.next()
123
>>> i.next()
'suo'
>>> i.next()
56.78
>>> i.next()

Traceback (most recent call last):
  File "<pyshell#359>", line 1, in <module>
    i.next()
StopIteration

自己写的for循环的迭代器的内部机制:

seq=[123,'suo',45.67,7896L]

fetch=iter(seq)

while True:
    try:
        i=fetch.next()
    except StopIteration:
        break
    print i

1)迭代序列
2)迭代字典
字典的迭代器会遍历它的键(keys).
语句 for eachKey in myDict.keys() 可以缩写为 for eachKey in myDict

Python 还引进了三个新的内建字典方法来定义迭代: myDict.iterkeys() (通过 keys 迭
代), myDict.itervalues() (通过 values 迭代), 以及 myDicit.iteritems() (通过 key/value 对
来迭代).

3)迭代文件
文件对象生成的迭代器会自动调用 readline() 方法. 这样, 循环就可以访问文本文件的所有行. 程序员可以使用 更简单的 for eachLine in myFile 替换 for eachLine in myFile.readlines()

4)创建迭代器
iter(obj)
如果你传递一个参数给 iter() , 它会检查你传递的是不是一个序列, 如果是, 那么很简单:
根据索引从 0 一直迭代到序列结束. 另一个创建迭代器的方法是使用类,  一个实现了 __iter__() 和 next() 方法的类可以作为迭代器使用.

iter(func, sentinel )
如果是传递两个参数给 iter() , 它会重复地调用 func , 直到迭代器的下个值等于
sentinel .

(7)列表解析(List comprehensions)

只用一行代码就可以创建包含特定内容的列表.

>>> [x ** 2 for x in range(6)]
[0, 1, 4, 9, 16, 25]

>>> seq = [11, 10, 9, 9, 10, 10, 9, 8, 23, 9, 7, 18, 12, 11, 12]
>>> [x for x in seq if x % 2]
[11, 9, 9, 9, 23, 9, 7, 11]

>>> [(x+1,y+1) for x in range(3) for y in range(5)]
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 1), (2, 2), (2,
3), (2, 4), (2, 5), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5)]

注:列表解析支持多重嵌套for 循环以及多个 if 子句.
在同一个列表中的这两个for循环,他们的关系是上下级的关系,即后一个for循环是在前一个for循环中的,并且变量的定义是在for循环中定义的,并不是在for循环前面进行的定义

>>> f = open('hhga.txt', 'r')
>>> len([word for line in f for word in line.split()])
91


(8)生成器表达式
生成器表达式是列表解析的一个扩展,生成器是特定的函数, 允许你返回一个值, 然后"暂停"代码的执行, 稍后恢复.

列表解析的一个不足就是必要生成所有的数据, 用以创建整个列表. 这可能对有大量数据的迭
代器有负面效应. 生成器表达式通过结合列表解析和生成器解决了这个问题.

生成器表达式与列表解析非常相似,而且它们的基本语法基本相同;
不过它并不真正创建数字列表, 而是返回一个生成器,这个生成器在每次计算出一个条目后,把这
个条目“产生”(yield)出来. 生成器表达式使用了"延迟计算"(lazy evaluation), 所以它在使用
内存上更有效

它是一个表达式,和列表解析有根本的不同,它返回一个表达式,即生成器。

示例:

>>> sum(len(word) for line in data for word in line.split())
408

f = open('/etc/motd', 'r')
longest = max(len(x.strip()) for x in f)
f.close()
return longest

注:生成器表达式用起来,和列表解析还是一样的,只是处理的机制不一样了,生成器表达式更加的高效,生成器表达式生成一个“懒惰”的序列表达式,可以将它传递给函数,进行进一步操作。
(9)
迭代器模块:itertools

42、异常
(1)通用的异常和异常捕获,使用多个except
def safe_float(obj):
    try:
        retval = float(obj)
    except ValueError:
        retval = 'could not convert non-number to float'
    except TypeError:
        retval = 'object type cannot be converted to float'
    return retval

(2)一个except处理多个异常,except 语句在处理多个异常时要求异常被放在一个元组里
def safe_float(obj):
    try:
        retval = float(obj)
    except (ValueError, TypeError):
        retval = 'argument must be a number or numeric string'
    return retval

(3)捕获所有异常
关于捕获所有异常, 你应当知道有些异常不是由于错误条件引起的. 它们是 SystemExit 和
KeyboardInterupt . SystemExit 是由于当前 Python 应用程序需要退出, KeyboardInterupt 代表
用户按下了 CTRL-C (^C) , 想要关闭 Python . 在真正需要的时候, 这些异常却会被异常处理捕获.
为了让人们摆脱不得不除创建两个处理器的惯用法,异常的继承结构有了调整:
所有异常的父类是:BaseException
KeyboardInterrupt 和 SystemExit 被从Exception 里移出, 和 Exception 平级:
- BaseException
|- KeyboardInterrupt
|- SystemExit
|- Exception
|- (all other current built-in exceptions) 所有当前内建异常

则,捕获所有异常的代码为:
try:
    ……
except BaseException, e:
    ……

(4)异常参数
异常参数将会是一个包含来自导致异常的代码的诊断信息的类实例.
def safe_float(object):
    try:
        retval = float(object)
    except (ValueError, TypeError), diag:
        retval = str(diag)
    return retval

(5)else子句
在try 范围中没有异常被检测到时,执行else 子句.

(6)finally子句
finally 子句是无论异常是否发生,是否捕捉都会执行的一段代码


下面是try-except-else-finally 语法的示例:
try:
    A
except MyException,e:
    B
else:
    C
finally:
    D

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值