Python in nutshell 2nd 简明翻译 (5)

本文详细介绍了Python中集合(Set)的操作方法与特性,包括成员检测、Set的各种方法及其应用场景,以及如何使用字典进行高效的数据存储与检索。此外还涉及了流程控制语句等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4.7 集合(Set)操作

集合是容器,用len可以得到内部元素个数。

集合是可迭代对象,其迭代顺序是随机的。

4.7.1 成员检测

k in S 用来检测S中是否包括元素k

4.7.2 Set方法

非改变方法(不改变应用方法的对象本身,它们也可以应用到fronzeset对象上):

S.copy( )

返回集合的浅拷贝。  

S.difference(S1)   (S – S1)

返回存在于S中,但不存在于S1中的元素。      

S.intersection(S1)  (S & S1)

返回SS1的交集。

S.issubset(S1)

SS1的子集,则返回true,否则为false   

S.issuperset(S1)

S1S的子集,则返回true,否则为false。等同于S1.issubset(S))

S.symmetric_difference(S1)  (S ^ S1)

返回不同时存在于SS1中的元素。

S.union(S1)   (S | S1)

返回SS1的合集。

 

改变方法(将会改变应用的对象本身,所以只能用于set对象;除pop方法外,只返回None。所有下列方法中引用到的x必须为可散列对象):

S.add(x)

添加新元素x。若x已存在,则不做任何处理。

S.clear( )

移除S中的所有元素,将S清空。 

S.discard(x)

移除元素x。若x不存在,则不做任何处理。

S.pop( )

移除并返回S中的一个元素。

S.remove(x)

移除元素x。若x不存在,则抛出异常KeyError

difference_update  (S -= S1)

intersection_update   (S &= S1)

symmetric_difference_update    (S ^= S1)

update    (S |= S1)

以上四个方法的处理算法等同于同名的非改变方法,只是这四个方法会改变调用方法的集合对象本身(update等同于union),同时只是返回None

特别注意的是,针对这八个方法(四个不改变方法与对应的四个改变方法),若通过方法调用,则参数S1可以使用任意可迭代对象(唯一的要求是,由此可迭代对象遍历得到的对象必须是可散列对象),但是若通过操作符运算或参数赋值运算来处理,则SS1必须是setfrozenset

利用pop方法,你可以一边迭代遍历Set,一边抛弃此元素,对于大集合来说,可以节省部分内存。

 

4.8 字典

首先,字典是容器对象,所以可以用len函数来获取其内部元素(键/值对)的个数。其次,字典是可迭代对象,但是它只针对key进行随机遍历,对于函数min(D),结果是最小的key值。

4.8.1 成员检测

k in D可以用来检测k是否是字典D的一个键值,若是则返回true,否则为false

4.8.2 索引操作

字典中的值通过索引来访问:v=D[k]。针对无效的k,系统将会抛出异常。

d = { 'x':42, 'y':3.14, 'z':7 }

d['x']                           # 42

d['z']                           # 7

d['a']                           # 抛出KeyError异常

通过在赋值语句中使用一个新的键值,就可以往字典中添加新的项目(键/值对)。

d = { 'x':42, 'y':3.14}

d['a'] = 16                      # d is now {'x':42, 'y':3.14,'a':16}

使用del语句:del D[k]可以移除与索引k相对应的项目(键/值对)。

4.8.3 字典操作

以下的方法中,k必须为可散列对象,x可以为任意对象。

非改变方法(不会改变应用方法的对象本身):

D.copy( )

返回字典的浅拷贝。

D.has_key(k)

若存在键值k,则返回true,否则false

D.items( )

返回一个新的包含字典D中所有项目(键值对)的List

D.keys( )

       返回一个新的包含字典D中所有键值的List

D.values( )

       返回一个新的包含字典D中所有值的List

D.iteritems( )

返回基于D中所有项目(键值对)之上的迭代器。

D.iterkeys( )

返回基于D中所有键值之上的迭代器。

D.itervalues( )

返回基于D中所有值之上的迭代器。

D.get(k[, x])

返回字典中与键值k相对的值,若此键值不存在,则返回x,若没有指定x,则返回None

 

改变方法(改变应用此方法的对象):

D.clear( )

移除字典D中所有项目,D成为一个空字典。

D.update(D1)

针对字典D1中的所有键值k,将D[k]设置为等于D1[k]

D.setdefault(k[, x])

k为字典D中合法的键值,则返回D[k],否则,将D[k]的值设置为x,并返回x

D.pop(k[, x])

k为字典D中合法的键值,则移除并返回D[k],否则,返回x。若没有指定x,则抛出异常。

D.popitem( )

移除并返回字典D中一个项目(键值对)。

 

itemskeys、以及values方法在返回新的List时都按一定顺序排序,如果多次调用这些方法,且在调用期间没有进行插入或移除操作,则将会一直保持此顺序。

iteritemsiterkeys、以及itervalues方法返回与上述三个方法的List结果一致的迭代器,且使用迭代器只需要更少的内存。只是要注意,在使用迭代器时,不能对更改键值集合,即不能插入或移除任何键值,而对于itemskeys、以及values方法在返回的List则没有此限制。

当你只需要使用一次字典,则可以使用popitem方法,它比items方法要节省内存。

setdefaultget方法的效果一样,只是当key不存在时,setdefault添加一个新项目,并将x设置为D[k]的值。同样对于pop方法,它与get一样返回字典项目,并随后将其移除。

要注意对于popget方法,若key不存在,get返回None,而pop抛出异常。

Python2.4中,update方法还可以接受包含键值对的可迭代对象作为参数。

 

4.9 print语句

print语句由关键字print加上零个或多个由逗号分隔的表达式组成。可以方便地用文本方式来显示值,对于debug特别有用。print语句针对每个表达式x显示的文本与str(x)的结果一致。

默认情况下,print会在各个表达式间插入空格,并在最后一个表达式后插入一个换行符,除非你在最后一个表达式后面接了一个逗号。

letter = 'c'

print "give me a", letter, "..."           # prints: give me a c... answer = 42

print "the answer is:", answer          # prints: the answer is: 42

 

print的输出目标是文件或类文件对象,即sys模块中stdout属性的值。若要重定向输入目标,如文件对象f,则可以用以下语句:

print >>f, rest of print statement

fNonw,则目标将会是sys.stdout,就像你不给出 >>f 的效果一样。

 

4.10. 流程控制语句

4.10.1. if 语句

if expression:

    statement(s)

elif expression:

    statement(s)

elif expression:

    statement(s)

...

else:

    statement(s)

 

可以使用任意Python表达式作为ifelif语句的条件。任何非零的数字或非空的容器都为true;零、None、或空容器都表示false。当你要检测布尔值时,请直接使用:

if x:

而不要使用如下格式:

if x is True:

if x == true:

if bool(x):

 

if语句的条件为真,则Python执行它的子语句,否则,将会对每个elif按顺序进行运算,碰到第一个为真的条件时,就运行这个子语句,之后整个if语句运行结束。

 

4.10.2. while 语句

while expression:

    statement(s)

 

while语句中也可以包含else子句,break子句,以及continue子句。

 

4.10.3. for 语句

for语句由一个可迭代对象进行控制:

for target in iterable:

    statement(s)

for语句也可以包含elsebreak、以及continue子句。

for语句中的控制变量target也可以是多个标识符,条件是可迭代对象中的项目必须是可迭代对象,且此可迭代对象中包含的对象数目与标识符数一致。如针对字典d

for key, value in d.items( ):

    if not key or not value:       # keep only true keys and values

        del d[key]

若可迭代对象的底层对象不是一个不变对象,则要注意在循环的过程中不要改变此对象。

若循环于一个List之上,不要插入、添加、或移除任何项目(重绑定是可以的)。

若循环于一个字典之上,不要添加或移除任何项目(重绑定是可以的)。

若循环于一个集合之上,不要添加或移除任何项目(任何改变都是不允许的)。

 

4.10.3.1. 迭代器

迭代器是这样的一个对象,假设为对象i,它拥有无参数方法i.next()供调用,i.next()返回可迭代对象的下一个项目,或者,若已迭代到了最后,则抛出一个StopIteration异常。

只要在你自己的类中定义这样一个next方法,就可以让类的实例成为可迭代对象。

大部分迭代器都可以隐式或显式地调用内置函数iter来实现。

调用Generator也会返回一个迭代器。

如下例,for语句会隐式地调用iter来得到一个迭代器。

for x in c:

    statement(s)

改成对等的显式调用以后,如下例如示:

_temporary_iterator = iter(c)

while True:

    try: x = _temporary_iterator.next( )

    except StopIteration: break

    statement(s)

然而,若iter(c)返回的迭代器inext()方法永远不会抛出StopIteration异常的话,for循环就永远不会停止(除非在循环体中有合适的breakreturn语句,或抛出异常)。iter(c)方法将会按顺序调用特定的方法c.__iter__()来得到基于c的一个迭代器。

模块itertools提供了许多好的构建与操纵迭代器的途径。

4.10.3.2. rangexrange函数

基于一个整数序列进行循环是最常见的循环场景,Python提供了内置的rangexrange来生成并返回整数序列。

要循环n次可以使用如下语句:

for i in xrange(n):

    statement(s)

range(x)返回一个List,包含有从0(包括在序列中)开始到x(不包括在序列中)结束的连续整数,对应的,range(x,y)返回的List包含有从x(包括在序列中)开始到y(不包括在序列中)结束的整数。而range(x,y,step)还可以为序列中的整数加上步长,若步长小于0,则从x开始进行递减。若step等于零,则抛出异常。

range函数返回一个普通的List对象,可以用于任意目的,但是xrange函数返回的是一个特定目的的对象(不是一个List对象),专用于需要迭代处理的地方,如for语句中。(请注意,为了兼容性的考虑,xrange返回的并不是一个可迭代对象,若你需要一个可迭代对象,请使用iter(xrange(…)))。这个由xrange返回的特定对象相比List而言节省内存,但是在其上进行循环操作时又需要花费比List更多的开销。

所以,基本上在你需要用一个整数序列时,可以一直使用range而不使用xrange

>>> print range(1, 5)

[1, 2, 3, 4]

>>> print xrange(1, 5)

xrange(1, 5)

在上面语句中,range返回了一个普通List,而xrange返回了一个特定的xrange类型的对象。

 

4.10.3.3. List解析

for循环的一个常用场景是,用一个表达式对可迭代对象的每个元素进行相应的处理,并得到一个新的结果列表。这种表达式被称为列表解析,因而不再需要通过一个语句块来完成,你可以在任何可以使用表达式的场合直接使用它(如函数调用的一个参数,return语句,或作为其它表达式的子表达式)。

列表解析语法如下:

[ expression for target in iterable lc-clauses ]

其中targetiterable的用法与一般的普通语句一样,只是要注意若iterable中的项目是tuple,则target中变量的个数要与之保持一致(如使用字典作为iterable,则target必须是由两个变量组成的变量组)。

lc-clauses是一组零个或多个子句,其格式如下:

for target in iterable

if expression

列表解析是与for循环有同等效果的语句,如:

result1 = [x+1 for x in some_sequence]

等同于:

result2 = []

for x in some_sequence:

    result2.append(x+1)

 

下面是使用if子句的例子:

result3 = [x+1 for x in some_sequence if x>23]

等同于:

result4 = []

for x in some_sequence:

    if x>23:

        result4.append(x+1)

下面是使用for子句的例子:

result5 = [x+y for x in alist for y in another]

等同于:

result6 = []

for x in alist:

    for y in another:

        result6.append(x+y)

从上面的例子中,可以看到对于具有多个for子句的列表解析,for循环的嵌套顺序与它们在解析语句中出现的顺序一致。

4.10.4. break 语句

break语句用来终止循环语句。若在嵌套循环中使用,则break只会终止包含它的那一层循环。

 

4.10.5. continue 语句

continue语句将会结束针对当前的迭代值的循环,程序将会继续此循环的下一个迭代值。

 

4.10.6. 循环语句中的else 子句

whilefor语句可以在尾部拥有一个可选的else子句。如果循环正常结束(for语句用完了所有的迭代值,while语句的每件变成为false;若使用了breakreturn或抛出了异常,则为非正常结束),则将会运行相应的else子句,否则,不运行else子句。

可以使用else子句来检测循环是否正常结束。

for x in some_container:

    if is_ok(x): break             # item x is satisfactory, terminate loop

else:

    print "Warning: no satisfactory item was found in container"

    x = None

 

4.10.7. pass语句

Python组合语句中的语句体至少必须要有一条语句,若你不需要程序做任何事,则可以使用pass语句,表示不做任何事,仅仅作为一个占位符存在。

请注意,对于空的defclass语句,你也可以使用docstring来代替pass语句。当然,你也可以使用pass语句。

 

4.10.8. tryraise语句

Python支持异常处理机制,包括有tryexceptfinnally、以及else子句。

程序可以使用raise语句来明确地引发一个异常。当异常发生时,程序正常的控制流程将会停止,Python会自动寻找一个合适的异常处理器。

 

4.10.9. with语句

Python 2.5中,新增了with语句,作为try/finally语句的一个更可读的替代。

 

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值