前几天介绍了“夏天一起虐口译活动”,有许多童鞋来咨询并加入成长会开始行动,现在的交传小组成员来自国内、英国、美国,我觉得这已经算是一个全球化的训练小组了。
但是我们做的事情不止这一个。Scalers的公众号介绍是“游走在口译世界的IT从业者”,所以,你不仅会在这里看到口译,也会看到IT。所以今天的文章是要介绍我们正在进行的另外一个学习小组“ScalersTalk成长会Coding小组”。
Coding小组其实就是在做编程方面的研习与训练。目前我们的节奏是共同刷一本书《Python核心编程》,每天刷10页,自行完成书上的练习,周末共同总结。现在已经进行了4周,所以今天和大家分享的是第4周的学习笔记。这其实就是集体学习了,我们小组共同学习一本书,共同实践,大家从各自地角度交流自己的理解,并且针对学习中的问题相互讨论。水平高一点的,就是在用经典教材做复习,扎实基础,水平入门的,就在用经典教材快速上手,并自行多投入时间自己开小灶。我们是从Python这门编程语言着手,在完成以后,会用这个语言做一些共同的项目,到后期会越来越好玩。
所以正好夏天到了,这个夏天除了可以在成长会一起虐口译,还可以在成长会一起刷Python。英语和计算机是现代社会的两大基础技能,把这两个搞好了,未来还是可以去想象一下的。
那为什么今天的标题叫《这个夏天,你还可以和美丽的姑娘一起刷Python》?我其实不是在用美女做营销话题,而是我的确注意到,在绝大多数和IT有关的社群或者公众号的读者中,男生的占比太高了,长期和机器与男生打交道,以至于有许多男生都不会好好说话了。我在的一些技术社群中,男女生比例差距如此之大,以至于群里只要有女生冒泡说话,男生们就像蜀犬吠日般狂热躁动……在这种环境下,身心都无法正常成长,何况学习技能和知识?
不过作为穿行在工科和文科世界的成长会而言,我们从来不存在这样的问题。我们的公众号性别比例非常均衡,而且女生甚至比男生多一些。所以哪怕是像编程、机器学习这样的小组,也有相当比例的美丽姑娘。由于大家是心向成长而相聚,所以阳光向上、积极乐观,也是社群的主旋律。我相信只有身心健康成长,我们才有全面的、稳定均衡的发展。
所以这个夏天,除了可以和成长会一起虐口译,还可以和美丽的姑娘一起刷Python,把你的视野充分打开,下次看到会Python又能做口译的姑娘,就不会汪汪汪了。
Coding小组目前仅面向成长会成员开放,要进入Coding小组,需要完成Codecademy.com上面的Python部分的全部学习课程与练习。
当然你也可以联系我,我相信你能找到我的QQ号码。
四周前我们开启了Coding小组的Python学习活动。这是我们的第4周学习笔记,由成长会聆木整理汇总。目前的节奏是每天10页Python核心编程,然后辅以相关的练习,周末线上总结讨论。以后你在ScalersTalk公众号,不仅仅能看到英语学习的进度,也能看到代码学习的进度。我们会把这件事情持续下去,用Python玩出更多的花样。如果你想来,可以加入成长会,和我们一起刷刷刷。
python中的集合类型
集合对象是一组无序排列的可哈希的值。集合支持in和not in操作符检查成员,也支持len()方法得到集合基数的大小,用for循环迭代集合的成员。
集合有两种不同的类型,可变集合和不可变集合。可变结合可以添加和删除元素,不可变集合不能这样子做。
创建集合类型和给集合赋值
集合的工厂方法 set()和 frozenset()来创建集合。
>>> s = set(‘cheeseshop’)
>>> s
set([‘c’, ‘e’, ‘h’, ‘o’, ‘p’, ‘s’])
>>> t = frozenset(‘bookshop’)
>>> t
frozenset([‘b’, ‘h’, ‘k’, ‘o’, ‘p’, ‘s’])
>>> frozenset([‘b’, ‘h’, ‘k’, ‘o’, ‘p’, ‘s’])
frozenset([‘b’, ‘h’, ‘k’, ‘o’, ‘p’, ‘s’])
>>> type(s)
<type ‘set’>
>>> type(t)
<type ‘frozenset’>
>>> len(s)
6
>>>
访问集合的值
使用in或者是not in来访问集合中的值
>>> ‘k’ in s
False
>>> ‘k’ in t
True
>>> ‘c’ not in t
True
>>> for i in s:
… print i
…
c
e
h
o
p
s
>>>
更新集合
使用add,update,remove以及set等方法来更新,添加和删除集合的成员。比如:
>>> s.add(‘z’)
>>> s
set([‘c’, ‘e’, ‘h’, ‘o’, ‘p’, ‘s’, ‘z’])
>>> s.update(‘pypi’)
>>> s
set([‘c’, ‘e’, ‘i’, ‘h’, ‘o’, ‘p’, ‘s’, ‘y’, ‘z’])
>>> s.remove(‘z’)
>>> s
set([‘c’, ‘e’, ‘i’, ‘h’, ‘o’, ‘p’, ‘s’, ‘y’])
>>> s -= set(‘pypi’)
>>> s
set([‘c’, ‘e’, ‘h’, ‘o’, ‘s’])
>>>
只有可变集合能被修改。试图修改不可变集合会引发异常
>>> t.add(‘z’)
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
AttributeError: ‘frozenset’ object has no attribute ‘add’
>>>
del方法是用来删除集合中的成员而使用的。
>>> del s
>>> s
集合类型操作符
Python 中的 in 和 not in 操作符决定某个元素是否是一个集合中的成员。
等价/不等价被用于在相同或不同的集合之间做比较。两个集合相等是指,对每个集合而言,当且仅当其中一个集合中的每个成员同时也是另一个集合中的成员。
>>> s = set(‘cheeshshop’)
>>> s
set([‘c’, ‘e’, ‘h’, ‘o’, ‘p’, ‘s’])
>>> u = set(‘cheap’)
>>> u
set([‘a’, ‘h’, ‘c’, ‘e’, ‘p’])
>>> s == u
False
>>> u = frozenset(s)
>>> u
frozenset([‘p’, ‘c’, ‘e’, ‘h’, ‘s’, ‘o’])
>>> s == u
True
>>>
子集/超集
Sets用Python的比较操作符检查某集合是否是其他集合的超集或子集。“小于”符号( <,<=)用来判断子集,“大于”符号( >, >= )用来判断超集。
“小于” 和 “大于”意味着两个集合在比较时不能相等。等于号允许非严格定义的子集和超集。
>>> set(‘shop’) < set(‘cheeseshop’)
True
>>> set(‘bookshop’) >= set(‘shop’)
True
>>>
集合类型操作符
联合( | )
联合(union)操作和集合的 OR(又称可兼析取(inclusive disjunction))其实是等价的,两个集合的联合是一个新集合,该集合中的每个元素都至少是其中一个集合的成员,即,属于两个集合其中之一的成员。联合符号有一个等价的方法,union()。
>>> s | u
set([‘c’, ‘e’, ‘h’, ‘o’, ‘p’, ‘s’])
>>>
交集( & )
两个集合的交集是一个新集合,该集合中的每个元素同时是两个集合中的成员,即,属于两个集合的成员。交集符号有一个等价的方法,intersection()。
>>> s & u
set([‘c’, ‘e’, ‘h’, ‘o’, ‘p’, ‘s’])
>>>
差补/相对补集( – )
两个集合(s 和 u)的差补或相对补集是指一个集合 C,该集合中的元素,只属于集合 s,而不属于集合 t。差符号有一个等价的方法,difference()。
>>> s – u
set([])
>>>
对称差分( ^ )
两个集合(s 和 u)的对称差分是指另外一个集合 C,该集合中的元素,只能是属于集合 s 或者集合 t的成员,不能同时属于两个集合。对称差分有一个等价的方法,symmetric_difference()。
>>> u = set(‘cheap’)
>>> u
set([‘a’, ‘h’, ‘c’, ‘e’, ‘p’])
>>> s = set(‘shopcheap’)
>>> s
set([‘a’, ‘c’, ‘e’, ‘h’, ‘o’, ‘p’, ‘s’])
>>> u ^ s
set([‘s’, ‘o’])
>>>
仅适用于可变集合的操作符
1 (|=) 等价于 update()
>>> s = set(‘cheeseshop’)
>>> u = frozenset(s)
>>> s |= set(‘pypi’)
>>> s
set([‘c’, ‘e’, ‘i’, ‘h’, ‘o’, ‘p’, ‘s’, ‘y’])
>>>
2 (&=) 保留/交集更新 保留(或交集更新)操作保留与其他集合的共有成员
>>> s = set(u)
>>> s &= set(‘shop’)
>>> s
set([‘h’, ‘s’, ‘o’, ‘p’])
>>>
3 (-=) 差更新 对集合 s 和 t 进行差更新操作 s-=t,差更新操作会返回一个集合,该集合中的成员是集合 s 去 除掉集合 t 中元素后剩余的元素。此方法和 difference_update()等价。
4 对称差分更新 ( ^= ) 返回一个集合,该集合中的成 员仅是原集合 s 或仅是另一集合 t 中的成员,剔除共有元素。
内建函数
len()
把集合作为参数传递给内建函数 len(),返回集合的基数(或元素的个数)。
集合类型工厂函数
set()和 frozenset()工厂函数分别用来生成可变和不可变的集合。如果不提供任何参数,默认会生成空集合。如果提供一个参数,则该参数必须是可迭代的,即,一个序列,或迭代器,或支持迭代的一个对象。
集合类型内建方法
内建方法 copy() 没有等价的操作符。和同名的字典方法一样,copy()方法比set(),frozenset(), 或 dict()这样的工厂方法复制对象的副本要快。
条件和循环
if语句
由三部分组成: 关键字本身, 用于判断结果真假的条件表达式, 以及当表达式为真或者非零时执行的代码块。
if expression:
expr_true_suite
多重条件表达式
单个 if 语句可以通过使用布尔操作符 and , or 和 not实现多重判断条件或是否定判断条件。
单一语句的代码块
如果一个复合语句(例如 if 子句, while 或 for 循环)的代码块仅仅包含一行代码, 那么它可以和前面的语句写在同一行上。
if make_hard_copy: send_data_to_printer()
else 语句
Python 提供了与 if 语句搭配使用的 else 语句。如果 if 语句的条件表达式的结果布尔值为假, 那么程序将执行 else 语句后的代码。
if expression:
expr_true_suite
else:
expr_false_suite
elif 是 Python 的 else-if 语句, 它检查多个表达式是否为真, 并在为真时执行特定代码块中的代码. 和 else 一样, elif 声明是可选的, 然而不同的是, if 语句后最多只能有一个 else语句, 但可以有任意数量的elif 语句。
if user.cmd == ‘create’:
action = “create item”
elif user.cmd == ‘delete’:
action = ‘delete item’
elif user.cmd == ‘update’:
action = ‘update item’
else:
action = ‘invalid choice… try again!’
条件表达式(即“三元操作符“)
C ? X : Y 三元运算符. ( C 是条件表达式; X 是 C 为 True 时的结果, Y 是 C 为 False 时的结果。使用三元操作符只需要一行完成条件判断和赋值操作, 而不需要像使用 if-else 语句实现对数字 x 和 y 的操作:
>>> x, y = 4, 3
>>> if x < y :
… smaller = x
… else:
… smaller = y
…
>>> x,y = 4,3
>>> smaller
3
>>>
而使用三元操作符则更加简洁:
>>> smaller = x if x < y else y
>>> smaller
3
>>>
while 语句
与 if声明相比,如果 if 后的条件为真,就会执行一次相应的代码块。 而 while 中的代码块会一直循环执行,直到循环条件不再为真。
while expression:
suite_to_repeat
例子:计数循环
count = 0
while (count < 9):
print ‘the index is:’, count
count += 1
必须小心地使用 while 循环, 因为有可能 condition 永远不会为布尔假. 这样一来循环就永远不会结束。
for 语句
for 循环会访问一个可迭代对象(例如序列或是迭代器)中的所有元素,并在所有条目都处理过后结束循环。
for iter_var in iterable:
suite_to_repeat
例子:用于序列类型
>>> for eachLetter in ‘Names’:
… print ‘current letter:’,eachLetter
…
current letter: N
current letter: a
current letter: m
current letter: e
current letter: s
>>>
迭代序列有三种基本方法
通过序列项迭代
>>> nameList = [‘Walter’, “Nicole”, ‘Steven’, ‘Henry’]
>>> for eachName in nameList:
… print eachName, “lim”
…
Walter lim
Nicole lim
Steven lim
Henry lim
>>>
通过序列索引迭代
>>> nameList = [‘Cathy’, “Terry”, ‘Joe’, ‘Heather’, ‘Lucy’]
>>> for nameIndex in range(len(nameList)):
… print “liu”,nameList[nameIndex]
…
liu Cathy
liu Terry
liu Joe
liu Heather
liu Lucy
>>>
使用了内建的 len() 函数获得序列长度, 使用 range() 函数创建了要迭代的序列。
使用项和索引迭代
>>> nameList = [‘Cathy’, “Terry”, ‘Joe’, ‘Heather’, ‘Lucy’]
>>> for i, eachLee in enumerate(nameList):
… print “%d %s Lee” %(i+1, eachLee)
…
1 Cathy Lee
2 Terry Lee
3 Joe Lee
4 Heather Lee
5 Lucy Lee
>>>
range() 内建函数
语法:range(start, end, step =1)。range() 会返回一个包含所有 k 的列表, 这里 start <= k < end , 从 start 到 end , k 每次递增 step . step 不可以为零,否则将发生错误。
>>> range(2, 19, 3)
[2, 5, 8, 11, 14, 17]
>>>
如果只给定两个参数,而省略 step, step 就使用默认值 1 。
range() 简略语法
range(end)
range(start, end)
>>> range(5)
[0, 1, 2, 3, 4]
>>>
>>> for count in range(2, 5):
… print count
…
2
3
4
>>>
xrange() 可能更为适合,因为它不会在内存里创建列表的完整拷贝。而且范围比range大,缺点只被用到for中。
与序列相关的内建函数
sorted(),reversed(), enumerate(),zip()
sorted():按从小到大顺序排列
reversed():按从大到小顺序排列
enumerate():返回下标 与 本身的值
在序列中循环时,索引位置和对应值可以使用 enumerate() 函数同时得到:
>>> for i,v in enumerate([‘tic’,‘janily’,‘reicky’]):
… print(i,v)
…
(0, ‘tic’)
(1, ‘janily’)
(2, ‘reicky’)
>>>
break 语句
Python 中的 break 语句可以结束当前循环然后跳转到下条语句,常用在当某个外部条件被触发(一般通过 if 语句检查),需要立即从循环中退出时。
continue 语句
它可以被用在 while 和 for 循环里. while 循环是条件性的, 而 for 循环是迭代的, 所以 continue 在开始下一次循环前要满足一些先决条件(前边的核心笔记中强调的), 否则循环会正常结束.
pass 语句
如果你在需要子语句块的地方不写任何语句,解释器会提示你语法错误。 因此,Python 提供了 pass 语句,它不做任何事情 – 即 NOP (No OPeration , 无操作 )。
if user_choice == ‘do_calc’:
pass else:
pass
pass 在任何需要语句块(一个或多个语句)的地方都可以使用(例如 elif , else , clasa , def , try , except , finally )。
迭代器和 iter() 函数
它为类序列对象提供了一个类序列的接口。比如序列,它们是一组数据结构,你可以利用它们的索引从 0 开始一直“迭代” 到序列的最后一个条目。
迭代方法
next() ,不是通过索引来计数。当你或是一个循环机制(例如 for 语句)需要下一个项时,调用迭代器的 next() 方法就可以获得它。条目全部取出后,会引发一个 StopIteration 异常,这并不表示错误发生,只是告诉外部调用者, 迭代完成。
reversed() 内建函数将返回一个反序访问的迭代器。enumerate() 内建函数同样也返回迭代器。
使用迭代器
>>> myTuple = (123,‘xyz’,45.67)
>>> i = iter(myTuple)
>>> i.next()
123
>>> i.next()
‘xyz’
>>> i.next()
45.67
>>> i.next()
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
StopIteration
>>>
字典与文件的迭代器
字典和文件是另外两个可迭代的 Python 数据类型. 字典的迭代器会遍历它的键(keys).语句 for eachKey in myDict.keys() 可以缩写为 for eachKey in myDict 。
d = {‘x’:1,‘y’:2,‘z’:3}
>>> for key in d:
… print key, ‘correspond to’,d[key]
…
y correspond to 2
x correspond to 1
z correspond to 3
>>>
文件迭代
文件对象生成的迭代器会自动调用 readline() 方法。这样, 循环就可以访问文本文件的所有行。或者使用更简单的 for eachLine in myFile 替换 for eachLine inmyFile.readlines() :
>>> myfile = open(‘/Users/chenweijie/Desktop/1.txt’)
>>> for eachline in myfile:
… print eachline, # \n
…
asfasdfasdgfasdsdgasdgsadgsagsdgsdgsa
asdfasdfsdfdfewqwetwe
>>>
可变对象和迭代器
迭代可变对象的时候修改它们并不是个好主意。这在迭代器出现之前就是一个问题。除列表外的其他序列都是不可变的,所以危险就发生在这里。一个序列的迭代器只是记录你当前到达第多少个元素,所以如果你在迭代时改变了元素,更新会立即反映到你所迭代的条目上。
如何创建迭代器
对一个对象调用 iter() 就可以得到它的迭代器. 它的语法如下:
iter(obj)
iter(func, sentinel )
如果传递一个参数给 iter() , 它会检查你传递的是不是一个序列, 如果是, 那么很简单:根据索引从 0 一直迭代到序列结束。
列表解析,用来动态地创建列表。
[expr for iter_var in iterable]
语句的核心是 for 循环, 它迭代 iterable 对象的所有条目。前边的 expr 应用于序列的每个成员,最后的结果值是该表达式产生的列表。迭代变量并不需要是表达式的一部分。
>>> [x ** 2 for x in range(6)]
[0, 1, 4, 9, 16, 25]
>>>
扩展语法
[expr for iter_var in iterable if cond_expr]
这个语法在迭代时会过滤/捕获满足条件表达式 cond_expr 的序列成员。
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]
>>>
生成器表达式
生成器是特定的函数, 允许你返回一个值, 然后“暂停“代码的执行, 稍后恢复。
它与列表解析非常相似,而且它们的基本语法基本相同;不过它并不真正创建数字列表, 而是返回一个生成器,这个生成器在每次计算出一个条目后,把这个条目“产生”(yield)出来. 生成器表达式使用了“延迟计算“(lazy evaluation), 所以它在使用内存上更有效.
(expr for iter_var in iterable if cond_expr)
>>> myfile.seek(0)
>>> sum(len(word) for line in myfile for word in line.split())
58
>>>
文件
文件对象不仅可以用来访问普通的磁盘文件, 而且也可以访问任何其它类型抽象层面上的“文 件“.处理“类文件“对象的情况. 例如实时地“打开一个 URL”来读取 Web 页面,在另一个独立的进程中执行一个命令进行通讯, 就好像是两个同时打开的文件, 一个用于读取, 另个用于写入。
文件内建函数[open()和file()]
内建函数 open() 的基本语法是:
file_object = open(file_name, access_mode=’r’, buffering=-1)
file_name 是包含要打开的文件名字的字符串, 它可以是相对路径或者绝对路径. 可选变量access_mode 也是一个字符串, 代表文件打开的模式. 通常, 文件使用模式 ‘r’, ‘w’, 或是 ‘a’模式来打开, 分别代表读取, 写入和追加. 还有个 ‘U’ 模式, 代表通用换行符支持。
使用 ‘r’ 或 ‘U’ 模式打开的文件必须是已经存在的. 使用 ‘w’ 模式打开的文件若存在则首先清空, 然后(重新)创建. 以 ‘a’ 模式打开的文件是为追加数据作准备的, 所有写入的数据都将追加到文件的末尾. 即使你 seek 到了其它的地方. 如果文件不存在, 将被自动创建, 类似以 ‘w’模式打开文件。
文件对象的访问模式
几种常见的模式:
r 以读方式打开
w 以写方式打开 (必要时清空)
a 以追加模式打开 (从 EOF 开始, 必要时创建新文件)
r+ 以读写模式打开
w+ 以读写模式打开
a+ 以读写模式打开
工厂函数 file()
open() 和 file() 函数具有相同的功能, 可以任意替换。
一般说来, 建议使用 open() 来读写文件, 想说明在处理文件对象时使用 file() , 例如 if instance(f, file) 。
通用换行符支持(UNS)
当你使用 ‘U’ 标志打开文件的时候, 所有的行分割符(或行结束符, 无论它原来是什么)通过 Python 的输入方法(例如 read*() )返回时都会被替换为换行符 NEWLINE(\n). (‘rU’ 模式也支持 ‘rb’ 选项) .
编译 Python 的时候,UNS 默认是打开的.
文件内建方法
文件方法可以分为四类: 输入, 输出, 文件内移动, 以及杂项操作.
输入
read() 方法用来直接读取字节到字符串中, 最多读取给定数目个字节. 如果没有给定 size参数(默认值为 -1)或者 size 值为负, 文件将被读取直至末尾.
readline() 方法读取打开文件的一行(读取下个行结束符之前的所有字节). 然后整行,包括行结束符,作为字符串返回.
readlines() 方法并不像其它两个输入方法一样返回一个字符串. 它会读取所有(剩余的)行然后把它们作为一个字符串列表返回.
输出
write() 内建方法功能与 read() 和 readline() 相反. 它把含有文本数据或二进制数据块的字符串写入到文件中去.
和 readlines() 一样,writelines() 方法是针对列表的操作, 它接受一个字符串列表作为参数, 将它们写入文件. 行结束符并不会被自动加入, 所以如果需要的话, 你必须在调用writelines()前给每行结尾加上行结束符.
当使用输入方法如 read() 或者 readlines() 从文件中读取行时, Python 并不会删除行结束符. 需要手动关闭文件。
f = open(‘myFile’, ‘r’)
data = [line.strip() for line in f.readlines()]
f.close()
文件内移动
seek() 方法可以在文件中移动文件指针到不同的位置. offset字节代表相对于某个位置偏移量. 位置的默认值为 0 , 代表从文件开头算起(即绝对偏移量), 1 代表从当前位置算起, 2 代表从文件末尾算起.
text() 方法是对 seek() 的补充; 它告诉你当前文件指针在文件中的位置 – 从文件起始算起,单位为字节.
文件迭代
for eachLine in f:
close() 通过关闭文件来结束对它的访问.
fileno() 方法返回打开文件的描述符.
文件方法杂项
读取文件到时候,建议使用文件迭代器, 每次只读取和显示一行:
filename = raw_input(‘Enter file name: ‘)
f = open(filename, ‘r’)
for eachLine in f:
print eachLine, f.close()
操作系统间的差异之一是它们所支持的行分隔符不同.当我们创建要跨这三个平台的应用的时候, 这些差异会让我们感觉非常麻烦(而且支持的平台越多越麻烦)。
Python 的 os 模块已经帮我们想到了这些问题. os 模块有五个很有用的属性可以来解决这些差异:
os 模块属性 描述
linesep 用于文件中分隔行的字符串
sep 用来分隔文件路径名字的字符串
pathsep 用于分隔文件路径的字符串
curdir 当前工作目录的字符串名称
pardir 当前工作目录父目录字符串名称
文件内建属性
file.encoding
文件所使用的编码 – 当 Unicode 字符串被写入数据时, 它们将自动使用 file.encoding 转换为字节字符串; 若 file.encoding 为 None 时使用系统默认编码.
file.mode
文件打开时使用的访问模式
file.name
文件名
文件系统
对文件系统的访问大多通过 Python 的 os 模块实现.
os 模块还负责处理大部分的文件系统操作,删除/重命名文件, 遍历目录树, 以及管理文件访问权限等.
另一个模块 os.path 可以完成一些针对路径名的操作. 它提供的函数可以完成管理和操作文件路径名中的各个部分, 获取文件或子目录信息, 文件路径查询等操作.
本文原文 http://scalerstalk.com/559-python-week4,首发ScalersTalk
本文作者Scalers,游走在口译世界的IT从业者。微信公众号ScalersTalk,网站ScalersTalk.com
ScalersTalk成长会回复“VIP”查看.口译100小时训练计划群C 456036104