# coding:utf-8
#---------------------------------------- print和import的更多信息 --------------------------------
#使用逗号输出
#打印多个表达式也是可行的,只要将它们用逗号隔开就好:
print ‘Age:‘ , 42 #可以看到,每个参数之间都插入了一个空格符。
#Age: 42
#如果想要同时输出文本和变量值,却不希望使用字符串格式化方法,那这个特性就非常有用:
name = ‘Gumby‘
salutation = ‘Mr.‘
greeting = ‘Hello,‘
print greeting, salutation, name
#Hello, Mr. Gumby
#注意,如果greeting变量里字符串不带逗号:
greeting = ‘Hello‘
#那么结果中怎么能得到逗号呢?
print greeting, ‘,‘, salutation, name #这样做是不行的,因为语句会在逗号前加入空格。下面是一种解决方案:
#Hello , Mr. Gumby
print greeting + ‘,‘, salutation, name
#Hello, Mr. Gumby
#如果在结尾处加上逗号,那么接下来的语句会与前一条语句在同一行打印。
print ‘Hello,‘,
print ‘world!‘
#Hello, world!
#把某件事作为另一件事导入
#从模块导入函数时候,通常可以使用
#import somemodule
#或者
#from somemodule import somefunction
#或者
#from somemodule import somefumction, anotherfunction, yetanotherfunction
#或者
#from somemodule import *
#只有确定自己想要从给定的模块导入所有功能是,才应该使用最后一个版本。
#如果两个模块都有open函数,使用如下方法:
#import somemodule
#module1.open(...)
#module2.open(...)
#但还有另外的选择,可以在语句末尾增加一个as子句,在该子句后给出想要使用的别名。
import math as foobar #整个模块提供别名
print foobar.sqrt(4)
#2.0
from math import sqrt as foobar #为函数提供别名
print foobar(4)
#2.0
#对于open函数,可以像下面这样使用:
#from module1 import open as open1
#from module2 import open as open2
#------------------------------------------ 赋值魔法 -----------------------------------------------------
#序列解包
#将多个值得序列解开,然后放到变量的序列中。
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
print values
#(1, 2, 3)
x, y, z = values
print x
#1
scoundrel = {‘name‘: ‘Robin‘, ‘girlfriend‘: ‘Marion‘}
key, value = scoundrel.popitem() #随机删除一对键和值,然后删除的键和值作为元组返回,这个元组赋予key和value变量
print key
#girlfriend
print value
#Marion
print scoundrel
#{‘name‘: ‘Robin‘}
#所解包的序列中的元素数量必须和放置在赋值符号=左边的变量数量完全一致,否则会报错。
#x, y, z = 1, 2 会报错
#x, y, z = 1, 2, 3, 4 会报错
#链式赋值
#链式赋值是将同一个值赋给多个变量的捷径。
x = y = 1
print x
#1
print y
#1
#效果同上
x = 1
x = y
print x
#1
print y
#1
#注意上面的语句和下面的语句不一定等价:
x = 1
y = 1
#增量赋值
#对于*,/,% 等标准运算符都适用
#增量赋值可以让代码更加紧凑和简练,很多情况下会更易读。
x = 2
x += 1
print x
#3
x *= 2
print x
#6
#对于其他数据类型也适用。
fnoed = ‘foo‘
fnoed += ‘bar‘
print fnoed
#foobar
fnoed *= 2
print fnoed
#foobarfoobar
#---------------------------------------------- 条件和条件语句 --------------------------------------------
#这就是布尔变量的作用
#下面的值在作为布尔表达式的时候,会被解释器看作假(false)
#False None 0 "" () [] {}
#其他一切都被解释为真,包括特殊值True
#标准布尔值为0表示假,1表示真
print True == 1
#True
print False == 0
#True
print True + False + 42
#43
#bool转换成布尔值
print bool(‘I think, therefore I am‘)
#True
print bool(42)
#True
print bool(‘‘)
#False
print bool(0)
#False
#条件执行和if语句
#如果条件(在if和冒号之间的表达式)判定为真,那么后面的语句块就会被执行。如果条件为假,语句块就不会被执行。
#name = raw_input(‘What is your name? ‘)
#if name.endswith(‘Gumby‘): #如果语句结尾是Gumby
# print ‘Hello, Mr. Gumby‘
#执行结果:
#What is your name? Gumby
#Hello, Mr. Gumby
#else子句
#name = raw_input(‘What is your name? ‘)
#if name.endswith(‘Gumby‘): #如果语句结尾是Gumby
# print ‘Hello, Mr. Gumby‘
#else:
# print ‘Hello, stranger‘
#执行结果:
#What is your name? abc
#Hello, stranger
#elif子句
#如果需要检查多个条件,就可以使用elif,它是else if的简写,也是if和else子句的联合使用,也就具有条件的else子句。
#num = input(‘Enter a number: ‘) 可以使用int(raw_input(‘Enter a number: ‘)来替代
#if num > 0:
# print ‘The number is positive‘
#elif num < 0:
# print ‘The number is negative‘
#else:
# print ‘The number is zero‘
#执行结果:
#Enter a number: 1
#The number is positive
#Enter a number: -1
#The number is negative
#Enter a number: 0
#The number is zero
#嵌套代码块
#if语句里面可以嵌套使用if语句,就像下面这样:
#name = raw_input(‘What is your name? ‘)
#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‘
#执行结果:
#What is your name? Mr. Gumby
#Hello,Mr. Gumby
#What is your name? Mrs. Gumby
#Hello,Mrs. Gumby
#What is your name? Gumby
#Hello, Gumby
#What is your name? abc
#Hello stranger
#更复杂的条件
#比较运算符
# x == y x 等于 y
# x < y x 小于 y
# x > y x 大于 y
# x >= y x 大于等于 y
# x <= y x 小于等于 y
# x != y x 不等于 y
# x is y x 和 y 是同一个对象
# x is not y x 和 y 是不同的对象
# x in y x 是 y 容器(列如,序列)的成员
# x not in y x 不是 y 容器(列如,序列)的成员
#注意如果偶然遇见x <> y 这样的表达式,它的意思其实就是x != y 不建议使用<>运算符,应该尽量避免使用它。
#在python中比较运算符和赋值运算符一样可以连接的---几个运算符可以连在一起使用,比如:
#0 < age < 100
#相等运算符
#如果想要知道两个东西是否相等,应该使用相等运算符,即两个等号==
print "foo" == "foo"
#True
print "foo" == "bar" #为何用双等于,一个等于是变量赋值,所以用双等于
#False
#is:同一性运算符
#判断是否一个对象,如果值相同,并不一定是一个对象
x = y = [1, 2, 3] #同一个对象
z = [1, 2, 3] #值相同,但和x y 不是一个对象
print x == y
#True
print x == z #值相同,所以True
#True
print x is y #是一个对象
#True
print x is z #不是一个对象,所以False
#False
#另外一个例子:
x = [1, 2, 3]
y = [2, 4]
print x is not y
del x[2]
y[1] = 1
y.reverse() #反向排序
print x
#[1, 2]
print y
#[1, 2]
print x == y
#True
print x is y
#False
#in 成员资格运算符
#name = raw_input(‘What is your name? ‘)
#if ‘s‘ in name:
# print ‘Your name contains the letter "s".‘
#else:
# print ‘Your name does not contain the letter "s".‘
#执行结果:
#What is your name? tom
#Your name does not contain the letter "s".
#What is your name? toms
#Your name contains the letter "s".
#字符串和序列比较
#字符串按照字母顺序排列
print "alpha" < "beta"
#True
#大写的话比较会乱,所以先转换小写再比较
print ‘FnOrD‘.lower() == ‘Fnord‘.lower()
#True
#其他序列比较,比较的是序列元素
print [1, 2] < [2, 1]
#True
print [2, [1, 4]] < [2,[1,5]]
#True
#布尔运算符
#多个条件写法:
#number = input(‘Enter a number between 1 and 10: ‘)
#if number <= 10:
# if number >= 1:
# print ‘Great!‘
# else:
# print ‘Wrong!‘
#else:
# print ‘Wrong!‘
#执行结果:
#Enter a number between 1 and 10: 1
#Great!
#Enter a number between 1 and 10: -1
#Wrong!
#Enter a number between 1 and 10: 11
#Wrong!
#这样写没问题,但方法太笨,简单方法:
#number = input(‘Enter a number between 1 and 10: ‘)
#if number <= 10 and number >= 1: #and运算符就是所谓的布尔运算符,它连接两个布尔值,并且在两者都为真时返回真,否则返回假。与它同类还有两个运算符,or和not。使用这3个运算符就可以随意结合真值。
# 还有更简单的表达式 1<=number<=10
# print ‘Great!‘
#else:
# print ‘Wrong!‘
#执行结果:
#Enter a number between 1 and 10: 1
#Great!
#Enter a number between 1 and 10: -1
#Wrong!
#Enter a number between 1 and 10: 11
#Wrong!
#短路逻辑惰性求值
#表达式x and y需要两个变量为真才为真,所以如果x为假,表达式就会立刻返回false,而不管y的值。
#表达式x or y,x为真时,它直接返回x值(True),否则返回y值(True)
#这有什么用?它主要是避免了无用的执行代码,可以作为一种技巧使用。假设用户应该输入名字,但也可以选择什么都不输入,这时可以用默认值‘<unknown>‘。可以用if语句但可以用更简洁的方式:
#name = raw_input(‘Please enter your name: ‘) or ‘<unknown>‘
# assert
#断言,要求程序代码中某些条件必须为真,否则报错退出,不再继续后续代码执行。用来测试调试程序代码的辅助条件。
age = 10
assert 0 < age < 100 #条件为真,不报错
#age = -1
#assert 0 < age < 100 #不为真,报错
#Traceback (most recent call last):
# File "Z:/CloudStation/***.py", line 96, in <module>
# assert 0 < age < 100
#AssertionError
#age = -1
#assert 0 < age < 100, ‘The age must be realistic‘
#条件后面添加字符串,可以用来注释解释错误信息。
#Traceback (most recent call last):
# File "Z:/CloudStation/***.py", line 96, in <module>
# assert 0 < age < 100, ‘The age must be realistic‘
#AssertionError: The age must be realistic
#------------------------------------------- 循环 --------------------------------------------------------
#while循环
x = 1
while x <= 100: #打印1到100
print x
x += 1
#name = ‘‘
#while not name: #如果输入空格也被接受,防止这种情况,可以修改while not name or name.isspace() 或者 while not name.strip()
# name = raw_input(‘Please enter your name: ‘)
#print ‘Hello, %s!‘ % name
#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
print range(0,10) #range函数,下限默认为0,不包含上限
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print range(10) #默认下限为0
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
#rang函数一次创建整个序列,xrange一次只创建一个数,当需要一个巨大序列时xrange会更高效
for number in range(1,101): #打印1到100,它比之前的while更简洁。
print number
#如果能使用for,就尽量不用while
#循环遍历字典元素
#一个简单的for语句就能遍历字典的所有键,就像遍历访问序列一样
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 key, ‘corresponds to‘, value
#y corresponds to 2
#x corresponds to 1
#z corresponds to 3
#一些迭代工具
#并行迭代
#程序可以同时迭代两个序列
names = [‘anne‘, ‘beth‘, ‘george‘, ‘damon‘]
ages = [12, 45, 32, 102]
#如果想要打印名字和对应的年龄:
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函数并行迭代,可以把两个序列"压缩"在一起,然后返回一个元组的列表
print 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函数也可以作用于任意多的序列,它可以作用不等长的序列,最短的序列用完的时候就会停止。
print zip(range(5),xrange(100000)) #不推荐用range替换xrange,range会计算所有的数字,xrange只计算前5个数字
#[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
#按索引迭代
names = [‘anne‘, ‘beth‘, ‘anne‘, ‘damon‘]
ages = [12, 45, 32, 102]
for name, age in zip(names, ages):
if ‘anne‘ in name: #找到索引进行替换
index = names.index(name)
names[index] = ‘[censored]‘
print names
#[‘[censored]‘, ‘beth‘, ‘anne‘, ‘damon‘]
#[‘[censored]‘, ‘beth‘, ‘[censored]‘, ‘damon‘]
names = [‘anne‘, ‘beth‘, ‘anne‘, ‘damon‘]
ages = [12, 45, 32, 102]
index = 0
for name, age in zip(names, ages):
if ‘anne‘ in name: #更好的方法
names[index] = ‘[censored]‘
print names
index += 1
#[‘[censored]‘, ‘beth‘, ‘anne‘, ‘damon‘]
#[‘[censored]‘, ‘beth‘, ‘[censored]‘, ‘damon‘]
#enumerate函数,可以在提供索引的地方迭代索引--值对
names = [‘anne‘, ‘beth‘, ‘anne‘, ‘damon‘]
ages = [12, 45, 32, 102]
for index, name in enumerate(names): #更好的方法
if ‘anne‘ in name:
names[index] = ‘[censored]‘
print names
# [‘[censored]‘, ‘beth‘, ‘anne‘, ‘damon‘]
# [‘[censored]‘, ‘beth‘, ‘[censored]‘, ‘damon‘]
#翻转和排序迭代
#reversed和sorted。它同列表的reverse和sort方法类似,但作用于任何序列或可迭代对象上,不是原地修改对象,而是返回翻转或排序后的版本:
print sorted([4, 3, 6, 8, 3])
#[3, 3, 4, 6, 8]
print sorted(‘Hello, world!‘)
#[‘ ‘, ‘!‘, ‘,‘, ‘H‘, ‘d‘, ‘e‘, ‘l‘, ‘l‘, ‘l‘, ‘o‘, ‘o‘, ‘r‘, ‘w‘]
print list(reversed(‘Hello, word!‘))
#[‘!‘, ‘d‘, ‘r‘, ‘o‘, ‘w‘, ‘ ‘, ‘,‘, ‘o‘, ‘l‘, ‘l‘, ‘e‘, ‘H‘]
print ‘‘.join(reversed(‘Hello, world!‘))
#!dlrow ,olleH
#跳出循环
#break
#结束(跳出)循环可以使用break语句。
from math import sqrt
for n in range(99, 0, -1): # -1是步长,负数是反向迭代
root = sqrt(n)
if root == int(root):
print n
break #跳出循环
#81
#continue
#continue意思是跳过剩余的循环体,但是不结束循环。当循环体很大而且很复杂的时候,这会很有用。
#for x in seq:
# if condition1:continue
# if condition2:continue
# if condition2:continue
# do_something()
# do_something_else()
# do_anoter_thing()
# etc()
#很多时候,只要使用if语句就可以了:
#for x in seq:
# if not (condition1 or condition2 or condition3):
# do_something()
# do_something_else()
# do_anoter_thing()
# etc()
#尽管continue语句非常有用,它却不是最本质的。应该习惯使用break语句,因为while True语句中会经常用到它。下一节会介绍:
#while True/break习语
while True: #无限循环
word = raw_input(‘Please enter a word: ‘)
if not word: break #满足条件跳出循环
# 处理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:
#循环中的else子句
#当循环内使用break语句时,通常是因为“找到”了某物或者因为某事“发生”了。在跳出前做一些事情很简单(比如在break上面加入print n),但是有些时候想要在没有跳出之前做些事情。
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
#列表推导式-轻量级循环
#列表推导式是利用其它列表创建新列表的一种方法。
print [x*x for x in range(10)]
#[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
print [x*x for x in range(10) if x % 3 == 0]
#[0, 9, 36, 81]
print [(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)]
#效果同上的for语句写法
result = []
for x in range(3):
for y in range(3):
result.append((x,y))
print result
#[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
girls = [‘alice‘, ‘bernic‘, ‘clarice‘]
boys = [‘chris‘, ‘arnold‘, ‘bob‘]
print [b+‘+‘+g for b in boys for g in girls if b[0] == g[0]] #比较第一位相同字母的方式
#[‘chris+clarice‘, ‘arnold+alice‘, ‘bob+bernic‘]
#上面例子效果不高,因为它会检查每个可能的配对。
#下面例子创建了一个叫做letterGirls的字典,其中每一项都把单字母作为键,以女孩名字组成列表作为值。在字典建立后,列表推导式循环整个男孩集合,并且查找那些和当前男孩名字首字母相同的女孩集合。
#这样列表推导式就不用尝试所有的男孩女孩的组合,检查首字母是否匹配。
girls = [‘alice‘, ‘bernic‘, ‘clarice‘]
boys = [‘chris‘, ‘arnold‘, ‘bob‘]
letterGirls = {}
for girl in girls:
letterGirls.setdefault(girl[0], []).append(girl)
print letterGirls #打印出来,查看循环情况
print [b+‘+‘+g for b in boys for g in letterGirls[b[0]]]
#{‘a‘: [‘alice‘]}
#{‘a‘: [‘alice‘], ‘b‘: [‘bernic‘]}
#{‘a‘: [‘alice‘], ‘c‘: [‘clarice‘], ‘b‘: [‘bernic‘]}
#[‘chris+clarice‘, ‘arnold+alice‘, ‘bob+bernic‘]
#------------------------------------------ 三人行 -----------------------------------------------------
#pass
#什么都没发生,用于代码没写完,暂时顶替
#name = raw_input(‘Please enter name: ‘)
#if name == ‘Ralph Auldus Mellish‘:
# print ‘Welcom!‘
#elif name == ‘Enid‘:
#还没完...
# pass #没想到写什么,但可以pass顶替,要不然程序会报错
#elif name == ‘Bill Gates‘:
# print ‘Access Denied‘
#del
#删除变量名字,值如果没有python会自动回收
scoundrel = {‘age‘:42, ‘first name‘: ‘Robin‘, ‘last name‘: ‘of Locksley‘}
robin = scoundrel
print scoundrel
#{‘last name‘: ‘of Locksley‘, ‘first name‘: ‘Robin‘, ‘age‘: 42}
print robin
#{‘last name‘: ‘of Locksley‘, ‘first name‘: ‘Robin‘, ‘age‘: 42}
scoundrel = None #当设置scoundrel为None的时候,字典通过robin还是可用
print scoundrel
#None
print robin
#{‘last name‘: ‘of Locksley‘, ‘first name‘: ‘Robin‘, ‘age‘: 42}
robin = None #当robin也设置为None的时候,字典就漂在内存里面,没有任何名字绑定在它上面,没有任何办法可以获取到它。就会被删除回收。也可以用None之外的其他值。同样会被删除回收。
print robin
#None
#另一种方法是del,它会删除对象引用和名字(但不会删除值)
x = 1
y = x
del x #x和y指向一个值,删除x变量只是名字,所以y的值还在
print y
#1
#使用exec和eval执行和求值字符串
#执行一个字符串的语句时exec
exec "print ‘Hello, world!‘"
#exec 需要放入到一个命名空间,但这个空间是用户自己的,并不会影响全局空间
from math import sqrt
scope = {} #增加scope,起到放置代码字符串命名空间作用的字典
exec ‘sqrt = 1‘ in scope
print sqrt(4) #没有覆盖sqrt函数
#2.0
print scope[‘sqrt‘] #通过exec赋值的变量sqrt只在它的作用域内有效
#1
#eval
#eval(用于求值)是类似于exec的内建函数。exec语句会执行一系列python语句(不返回值),而eval会计算python表达式(以字符串形式书写),并且返回结果值。
#print eval (raw_input("Enter an arithmetic expression: "))
#Enter an arithmetic expression: 6 + 18 * 2
#42
#跟exec一样,eval也可以使用命名空间
scope = {}
scope[‘x‘] = 2
scope[‘y‘] = 3
print eval(‘x * y‘, scope)
#6
scope = {}
exec ‘x = 2‘ in scope
print eval(‘x * x‘, scope)
#4
#涉及函数
#chr(n) 当传入序号n时,返回n所代表的包含一个字符的字符串,(0 <= n < 256)
#eval(source[, globals[, locals]]) 将字符串作为表达式计算,并且返回值
#enumerate(seq) 产生用于迭代的(索引,值)对
#ord(c) 返回单字符字符串的int值
#rang([start,] stop[, step]) 创建整数的列表
#reversed(seq) 产生seq中值的反向版本,用于迭代
#sorted(seq[,cmp][,key][,reverse]) 返回seq中值排序后的列表
#xrange([start,]stop[,step]) 创造xrange对象用于迭代
#zip(seq1,_seq2...) 创造用于并行迭代的新序列