Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32
#Chapter 5 条件, 循环和其他语句
#5.1 print和import的更多信息
#对于很多应用程序来说, 使用logging模块记日志比print语句更合适
#5.1.1 使用逗号输出
#可以看到, 每隔参数之间都自动插入了一个空格符
>>> print 'Age:',42
Age: 42
>>> 1,2,3
(1, 2, 3)
#print的参数并不像我们预期那样构成一个元组
>>> print 1,2,3
1 2 3
>>> print (1,2,3)
(1, 2, 3)
>>> name='Gumby'
>>> salution='Mr.'
>>> greeting='Hello,'
>>> print greeting, salution, name
Hello, Mr. Gumby
>>> greeting='Hello'
>>> print greeting, ',', salution, name
Hello , Mr. Gumby
>>> print greeting + ',', salution, name
Hello, Mr. Gumby
#如果在结尾处加上逗号,那么接下来的语句会与前一语句在同一行打印(只在脚本中起作用,在交互式Python会话中无效)
print 'Hello,',
print 'world!'
#输出Hello, world!
#5.1.2 import语句
#import somemodule
#from somemodule import somefunction
#from somemodule import somefunction, anotherfunction, yetanotherfunction
#from somemodule import *
#为模块提供别名
>>> import math as foobar
>>> foobar.sqrt(4)
2.0
#为函数提供别名
>>> from math import sqrt as foobar
>>> foobar(4)
2.0
#给不同模块中的同名函数提供别名
#from module1 import open as open1
#from module2 import open as open2
#5.2 赋值魔法
#5.2.1 序列解包(sequence unpacking)
>>> x, y, z = 1, 2, 3
>>> print x, y, z
1 2 3
>>> x, y = y, x
>>> print x, y, z
2 1 3
>>> values = 1,2,3
>>> values
(1, 2, 3)
>>> x,y,z=values
>>> x
1
>>> y
2
>>> z
3
>>> scoundrel={'name':'Robin', 'girlfriend':'Marion'}
>>> key, value = scoundrel.popitem()
>>> key
'girlfriend'
>>> value
'Marion'
>>> x,y,z = 1,2

Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    x,y,z = 1,2
ValueError: need more than 2 values to unpack
>>> x,y,z=1,2,3,4

Traceback (most recent call last):
  File "<pyshell#32>", line 1, in <module>
    x,y,z=1,2,3,4
ValueError: too many values to unpack
#Python 3.0 中有另外一个解包的特性
#a,b,rest*=[1,2,3,4]
#rest的结果将会是[3,4]
#5.2.2 链式赋值
#x=y=somefunction
#等效于
#y=somefunction
#x=y

#5.2.3 增量赋值(augmented assignment)
>>> x=2
>>> x += 1
>>> x *= 2
>>> x
6
>>> fnord = 'foo'
>>> fnord += 'bar'
>>> fnord *= 2
>>> fnord
'foobarfoobar'
#语句块: 缩排的乐趣
#5.4 条件和条件语句
# False None 0 "" '' () [] {} 会被解释器看做假
>>> True
True
>>> False
False
>>> True == 1
True
#标准的布尔值为False(0)和True(1)
>>> False == 0
True
>>> True + False + 42
43
#bool函数可以用来(和list, str以及tuple类似)转换其他值
>>> bool('I think, therefore I am')
True
>>> bool(42)
True
>>> bool('')
False
>>> bool(0)
False
>>> bool([])
False
>>> bool(())
False
>>> bool({})
False
#5.4.2 条件执行和if语句
>>> name = raw_input('What is your name? ')
What is your name? Gumby
>>> if name.endswith('Gumby'):
...     print 'Hello, Mr. Gumby'
...
Hello, Mr. Gumby
#5.4.3 else子句
>>> name = raw_input('What is your name? ')
What is your name? Jon
>>> if name.endswith('Gumby'):
...     print 'Hello, Mr. Gumby'
... else:
...     print 'Hello, stranger'
...
Hello, stranger
#5.4.4 elif子句
>>> num = input('Enter a number: ')
Enter a number: 0
>>> if num > 0:
...     print 'The number is positive'
... elif num < 0:
...     print 'The number is negative'
... else:
...     print 'The number is zero'
...
The number is zero
#5.4.5 嵌套代码块
>>> name = raw_input('What is your name? ')
What is your name? Mrs. Gumby
>>> if name.endswith('Gumby'):
...     if name.startswith('Mr.'):
...             print 'Hello, Mr. Gumby'
...     elif name.startswith('Mrs.'):
...             print 'Hello, Mrs. Gumby'
...     else:
...             print 'Hello, Gumby'
... else:
...     print 'Hello, stranger'
...
Hello, Mrs. Gumby
#链式比较运算
#比较对象的时候可以使用内建的cmp函数
>>> age=10
>>> 0<age<100
True
>>> age=-1
>>> 0<age<100
False
#相等运算符
>>> "foo" == "foo"
True
>>> "foo" == "bar"
False
>>> "foo" = "foo"
  File "<stdin>", line 1
SyntaxError: can't assign to literal
#同一性运算符
#避免将is运算符用于比较类似数值和字符串这类不可变值.
>>> x=y=[1,2,3]
>>> z=[1,2,3]
>>> x == y
True
>>> x == z
True
>>> x is y
True
>>> x is z
False
>>>
>>> x is z
False
>>> x = [1,2,3]
>>> y = [2,4]
>>> x is not y
True
>>> del x[2]
>>> y[1]=1
>>> y.reverse()
>>> x == y
True
>>> x is y
False
#in: 成员资格运算符
>>> name = raw_input('What is your name? ')
What is your name? Jonathan
>>> if 's' in name:
...     print 'Your name contains the letter "s".'
... else:
...     print 'Your name does not contain the letter "s".'
...
Your name does not contain the letter "s".
>>> "alpha" < "beta"
True
>>> 'FnOrd'.lower() == 'Fnord'.lower()
True
>>> [1,2] < [2,1]
True
>>> [2,[1,4]]<[2,[1,5]]
True
#布尔运算符

>>> number = input('Enter a number between 1 and 10: ')
Enter a number between 1 and 10: 8
>>> if number <= 10:
...     if number >=1:
...             print 'Great!'
...     else:
...             print 'Wrong!'
... else:
...     print 'Wrong!'
...
Great!
>>> number = input('Enter a number between 1 and 10: ')
Enter a number between 1 and 10: 6
>>> if number <= 10 and number >= 1:
...     print 'Great!'
... else:
...     print 'Wrong!'
...
Great!
>>> number = input('Enter a number between 1 and 10: ')
Enter a number between 1 and 10: 11
>>> if 1 <= number <= 10:
...     print 'Great!'
... else:
...     print 'Wrong!'
...
Wrong!
>>> name = raw_input('Please enter your name: ') or '<unknown>'
Please enter your name:
>>> name
'<unknown>'
#短路逻辑和条件表达式
#类似C和Java中的三元运算符
>>> name = 'Jon'if True else 'Jack'
>>> name
'Jon'
>>> name = 'Jon'if False else 'Jack'
>>> name
'Jack'
#5.4.7 断言
>>> age = 10
>>> assert 0 < age < 100
>>> age = -1
>>> assert 0 < age < 100
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError
#条件后可以添加逗号和字符串,用来解释断言
>>> age = -1
>>> assert 0 < age < 100, 'The age must be realistic'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: The age must be realistic
#5.5 循环
#5.5.1 while循环
>>> x=1
>>> while x <= 100:
...     print x
...     x +=1
...
1
2
3
...
100
>>> x
101

>>> name = ''
>>> while not name:
...     name = raw_input('Please enter your name: ')
...
Please enter your name:
Please enter your name:
Please enter your name: Jon
>>> print 'Hello, %s!' % name
Hello, Jon!
>>> name = ''
>>> while not name or name.isspace():
...     name = raw_input('Please enter your name: ')
...
Please enter your name:
Please enter your name:
Please enter your name: Chan
>>> print 'Hello, %s!' % name
Hello, Chan!
>>> while not name.strip():
...     name = raw_input('Please enter your name: ')
...
>>> name = ''
>>> while not name.strip():
...     name = raw_input('Please enter your name: ')
...
Please enter your name:
Please enter your name:
Please enter your name: Kingston
>>> print 'Hello, %s!' % name
Hello, Kingston!

#5.5.2 for循环
>>> words=['this', 'is', 'an', 'ex', 'parrot']
>>> for word in words:
...     print word
...
this
is
an
ex
parrot
>>> numbers = [0,1,2,3,4,5,6,7,8,9]
>>> for number in numbers:
...     print number
...
0
1
2
3
4
5
6
7
8
9
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
#如果能使用for循环,就尽量不用while循环
#当需要迭代一个巨大的序列时,xrange会比range更高效
>>> for number in range(1,5):
...     print number
...
1
2
3
4
#5.5.3 循环遍历字典元素
>>> d={'x':1, 'y':2, 'z':3}
>>> for key in d:
...     print key, 'corresponds to', d[key]
...
y corresponds to 2
x corresponds to 1
z corresponds to 3
>>> for key, value in d.items():
...     print kye, 'corresponds to', value
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
NameError: name 'kye' is not defined
>>> for key, value in d.items():
...     print key, 'corresponds to', value
...
y corresponds to 2
x corresponds to 1
z corresponds to 3
>>>


#5.5.4 一些迭代工具
#并行迭代
>>> names = ['anne', 'beth', 'george', 'damon']
>>> ages = [12, 45, 32, 102]
>>> for in in range(len(names)):

SyntaxError: invalid syntax
>>> for i in range(len(names)):
	print names[i], 'is', ages[i], 'year old'


anne is 12 year old
beth is 45 year old
george is 32 year old
damon is 102 year old
>>> for i in range(len(names)):
	print names[i], 'is', ages[i], 'years old'


anne is 12 years old
beth is 45 years old
george is 32 years old
damon is 102 years old
>>> zip(names, ages)
[('anne', 12), ('beth', 45), ('george', 32), ('damon', 102)]
>>> for name, age in zip(names, ages):
	print name, 'is', age, 'years old'


anne is 12 years old
beth is 45 years old
george is 32 years old
damon is 102 years old
>>> zip(range(5), xrange(100000000))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
#在索引上迭代
>>> strings = ['I am xxx', 'I like losing my face', 'Say goodbye']
>>> for string in strings:
	index = strings.index(string) # Search for the string in the list of strings
	strings[index]='[censored]'


>>> strings
['[censored]', '[censored]', '[censored]']
>>> strings = ['I am xxx', 'I like losing my face', 'Say goodbye']
>>> for string in strings:
	if 'xxx'in strings:
		index = strings.index(string) # Search for the string in the list of strings
		strings[index]='[censored]'


>>> strings
['I am xxx', 'I like losing my face', 'Say goodbye']
>>> strings = ['I am xxx', 'I like losing my face', 'Say goodbye']
>>> for string in strings:
	if 'xxx' in string:
		index = strings.index(string) # Search for the string in the list of strings
		strings[index]='[censored]'


>>> 
>>> string
'Say goodbye'
>>> strings
['[censored]', 'I like losing my face', 'Say goodbye']
>>> ['I am xxx', 'I like losing my face', 'Say goodbye']
['I am xxx', 'I like losing my face', 'Say goodbye']
>>> index = 0
>>> for string in strings:
	if 'xxx' in string:
		strings[index]='[censored]'
index += 1
SyntaxError: invalid syntax
>>> index = 0
>>> for string in strings:
	if 'xxx' in string: strings[index]='[censored]'
	index += 1


>>> strings
['[censored]', 'I like losing my face', 'Say goodbye']
>>> ['I am xxx', 'I like losing my face', 'Say goodbye', 'xxx is a sensitive word']
['I am xxx', 'I like losing my face', 'Say goodbye', 'xxx is a sensitive word']
>>> for index, string in enumerate(strings):
	if 'xxx' in string:
		strings[index]='[censored]'


>>> strings
['[censored]', 'I like losing my face', 'Say goodbye']
>>> strings = ['I am xxx', 'I like losing my face', 'Say goodbye', 'xxx is a sensitive word']
#enumerate函数可以在提供索引的地方迭代索引-值对.
>>> for index, string in enumerate(strings):
	if 'xxx' in string:
		strings[index]='[censored]'


>>> strings
['[censored]', 'I like losing my face', 'Say goodbye', '[censored]']

#翻转和排序迭代
>>> sorted([4,3,6,8,3])
[3, 3, 4, 6, 8]
>>> sorted('Hello, world!')
[' ', '!', ',', 'H', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r', 'w']
>>> list(reversed('Hello, world'))
['d', 'l', 'r', 'o', 'w', ' ', ',', 'o', 'l', 'l', 'e', 'H']
>>> ''.join(reversed('Hello, world!'))
'!dlrow ,olleH'

#5.5.5 跳出循环
#break
>>> from math import sqrt
>>> for n in range(99, 0, -1);
SyntaxError: invalid syntax
>>> for n in range(99, 0, -1):
	root = sqrt(n)
	if root == int(root):
		print n
		break


81
# continue
# while True/break习惯用法
>>> word = 'dummy'
>>> while word:
	word = raw_input('Please enter a word: ')
	# 处理word:
	print 'The word was ' + word


Please enter a word: first
The word was first
Please enter a word: second
The word was second
Please enter a word: 
The word was 

>>> word = raw_input('Please enter a word: ')
Please enter a word: first
>>> while word:
	print 'The word was ' + word
	word = raw_input('Please enter a word: ')


The word was first
Please enter a word: second
The word was second
Please enter a word: 

>>> while True:
	word = raw_input('Please enter a word: ')
	if not word: break
	print 'The word was ' + word


Please enter a word: first
The word was first
Please enter a word: second
The word was second
Please enter a word: 
#5.5.6 循环中else子句
#原始方案
from math import sqrt
break_out = False
for n in range(99, 81, -1):
	root = sqrt(n)
	if root == int(root):
		break_out = True
		print n
		break

if not break_out:
	print "Didn't find it!"


#结果Didn't find it!

#改进方案
from math import sqrt
for n in range(99, 81, -1):
	root = sqrt(n)
	if root == int(root):
		print n
		break
else:
	print "Didn't find it!"
#结果Didn't find it!

#列表推导式(list comprehension)--轻量级循环

>>> [x*x for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
#可以和if子句联合使用
>>> [x*x for x in range(10) if x % 3 == 0]
[0, 9, 36, 81]
>>> [(x,y) for x in range(3) for y in range(3)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
>>> 
>>> result=[]
>>> for x in range(3):
	for y in range(3):
		result.append((x,y))


>>> result
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

>>> girls=['alice', 'bernice', 'clarice']
>>> boys=['chris', 'arnold', 'bob']
>>> [b+'+'+g for b in boys for g in girls if b[0] == g[0]]
['chris+clarice', 'arnold+alice', 'bob+bernice']

#更优方案
>>> girls = ['alice', 'bernice', 'clarice']
>>> boys = ['chris', 'arnold', 'bob']
>>> letterGirls={}
>>> for girl in girls:
	letterGirls.setdefault(girl[0], []).append(girl)


>>> print [b+'+'+g for b in boys for g in letterGirls[b[0]]]
['chris+clarice', 'arnold+alice', 'bob+bernice']
>>> letterGirls
{'a': ['alice'], 'c': ['clarice'], 'b': ['bernice']}


#5.7 三人行 pass, del 和 exec

#5.7.1 什么都没发生

>>> name = 'Bill Gates'
>>> if name == 'Ralph Auldus Melish':
...     print 'Welcome!'
... elif name == 'Enid':
...     pass
... elif name == 'Bill Gates':
...     print 'Access Denied'
...
Access Denied

#5.7.2 使用del删除
>>> scoundrel = {'age':42, 'first name':'Robin', 'last name':'of Locksley'
>>> robin = scoundrel
>>> scoundrel
{'last name': 'of Locksley', 'first name': 'Robin', 'age': 42}
>>> robin
{'last name': 'of Locksley', 'first name': 'Robin', 'age': 42}
>>> scoundrel = None
>>> scoundrel
>>> print scoundrel
None
>>> robin
{'last name': 'of Locksley', 'first name': 'Robin', 'age': 42}
>>> x = 1
>>> y = x
>>> x=1
>>> del x
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> x = ['Hello', 'world']
>>> y = x
>>> y[1]='Python'
>>> x
['Hello', 'Python']
>>> del x
>>> y
['Hello', 'Python']

#5.7.3 使用exec和eval执行和求值字符串
# exec 在 Python 3.0 中是一个函数而不是语句
>>> exec "print 'Hello, world!'"
Hello, world!
>>> from math import sqrt
>>> exec "sqrt=1"
>>> sqrt(4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable

#命名空间,或称为作用域(scope)
#可以通过in <scope> 来实现, 其中的<scope>就是起到放置代码字符串命名空间作用的字典
>>> from math import sqrt
>>> scope={}
>>> exec 'sqrt = 1' in scope
>>> sqrt(4)
2.0
>>> scope ['sqrt']
1
>>> len(scope)
2
>>> scope.keys()
['__builtins__', 'sqrt']
# eval--求值字符串
>>> eval(raw_input("Enter an arithmetic express: "))
Enter an arithmetic express: 6 + 18 * 2
42
>>> scope={}
>>> scope['x']=2
>>> scope['y']=3
>>> eval('x * y', scope)
6
>>> scope = {}
>>> exec 'x=2' in scope
>>> eval('x*x', scope)
4
>>>

#5.8 小结
#打印--print语句可以用来打印由逗号隔开的多个值. 如果语句以逗号结尾,随后的print语句会在同一行内接续打印
#导入--可以用as对模块或函数提供别名
#赋值--通过 序列解包 和 链式赋值 功能, 多个变量可以一次性赋值, 通过 增量赋值 可以原地改变变量
#块--块是通过缩排使语句成组的一种方法. 块可以在条件以及循环语句中使用,也可以在函数和类中使用
#条件--几个条件可以串联使用if/elif/else. 还有一个变体叫做条件表达式,形如a if b else c.
#断言--断言简单来说就是肯定某事(布尔表达式)为真, 也可在它后面跟上这么认为的原因.
#循环--可以使用continue语句跳过块中的其他语句然后继续下一次迭代, 或使用break语句跳出循环
#    还可以选择在循环结尾加上else子句, 当没有执行循环内部的break语句时便会执行else子句中的内容.
#列表推导式--是看起来像循环的表达式.通过它, 可以从旧列表中产生新的列表, 对元素应用函数, 过滤掉不需要的元素,等等.
#pass, del, exec 和 eval 语句. pass语句什么都不做, 可以作为占位符使用. del语句用来删除变量(名称),或数据结构的一部分, 但是不能用来删除值.
#    exec语句用与执行Python程序相同的方式来执行字符串. 内建的eval函数对字符串中的表达式进行求值并返回结果.

#5.8.1 本章的新函数
#chr(n)		返回序数n所代表的字符的字符串(0<=n<=256)
#eval(source[, globals[, locals]])	将字符串作为表达式计算,并且返回值
#enumerate	产生用于迭代的(索引,值)对
#ord(c)		返回单字符字符串的int值
#range([start,] stop[, step])	创建整数的列表
#reversed(seq)	产生seq中值的反向副本, 用于迭代
#sorted(seq[, cmp][, key][, reverse])	返回seq中值排序后的列表副本
#xrange([start,] stop[, step]) 创建xrange对象用于迭代
#zip(seq1, seq2,...)	创建用于并行迭代的新序列