本課主題

  • Set 集合和操作实战
  • 函数介紹和操作实战
  • 参数的深入介绍和操作实战
  • format 函数操作实战
  • lambda 表达式介绍
  • 文件操作函数介紹和操作实战
  • 本周作业

Set 集合和操作实战

Set 是一个无序不容许重复的序列

创建集合有两种方式:

  1. 第一种是通过直接创建、例如:s = {11,22}

    1 >>> se = {11,222,11,222}
    2 >>> print(se)
    3 {11, 222}
    4 >>> type(se)
    5 <class 'set'>

    创建集合 方法一

  2. 第二种是通过转换。从一个可迭代类型的数组、元组转换成集合 Set。例如:s = Set(list)

    1 >>> li = [11,22,11,33,11,44,55]
    2 >>> se = set(li) #把列表转换成集合
    3 >>> se
    4 {33, 11, 44, 22, 55}
    5 >>> type(se)
    6 <class 'set'>

    创建集合 方法二

    原理:在调用 Set 函数时,它会自动调用 __intit__ 方法,这叫构造方法 ,其实内部会执行一个 For 循环,循环这个"可迭代对象"里的所有元素,一个一个添加到集合里(什么是构造方法会在后期学到面向对象后再分享)

Set 集合的功能

这是Set 集合在 Python3.5.2的源码,我把它贴进来,里面有很多双下划线的方法,现在我都不知道是什么,让我了解后会回来补充一下。现在最主要的是要了解下面这几个集合的功能:我把它归类为添加、更新、找不同、找相同、删除和返回Boolean值六大类。

class set(object):"""set() -> new empty set objectset(iterable) -> new set objectBuild an unordered collection of unique elements."""def add(self, *args, **kwargs): # real signature unknown"""Add an element to a set.This has no effect if the element is already present."""passdef clear(self, *args, **kwargs): # real signature unknown""" Remove all elements from this set. """passdef copy(self, *args, **kwargs): # real signature unknown""" Return a shallow copy of a set. """passdef difference(self, *args, **kwargs): # real signature unknown"""Return the difference of two or more sets as a new set.(i.e. all elements that are in this set but not the others.)"""passdef difference_update(self, *args, **kwargs): # real signature unknown""" Remove all elements of another set from this set. """passdef discard(self, *args, **kwargs): # real signature unknown"""Remove an element from a set if it is a member.If the element is not a member, do nothing."""passdef intersection(self, *args, **kwargs): # real signature unknown"""Return the intersection of two sets as a new set.(i.e. all elements that are in both sets.)"""passdef intersection_update(self, *args, **kwargs): # real signature unknown""" Update a set with the intersection of itself and another. """passdef isdisjoint(self, *args, **kwargs): # real signature unknown""" Return True if two sets have a null intersection. """passdef issubset(self, *args, **kwargs): # real signature unknown""" Report whether another set contains this set. """passdef issuperset(self, *args, **kwargs): # real signature unknown""" Report whether this set contains another set. """passdef pop(self, *args, **kwargs): # real signature unknown"""Remove and return an arbitrary set element.Raises KeyError if the set is empty."""passdef remove(self, *args, **kwargs): # real signature unknown"""Remove an element from a set; it must be a member.If the element is not a member, raise a KeyError."""pass__hash__ = Nonedef symmetric_difference(self, *args, **kwargs): # real signature unknown"""Return the symmetric difference of two sets as a new set.(i.e. all elements that are in exactly one of the sets.)"""passdef symmetric_difference_update(self, *args, **kwargs): # real signature unknown""" Update a set with the symmetric difference of itself and another. """passdef union(self, *args, **kwargs): # real signature unknown"""Return the union of sets as a new set.(i.e. all elements that are in either set.)"""passdef update(self, *args, **kwargs): # real signature unknown""" Update a set with the union of itself and others. """passdef __and__(self, *args, **kwargs): # real signature unknown""" Return self&value. """passdef __contains__(self, y): # real signature unknown; restored from __doc__""" x.__contains__(y) <==> y in x. """passdef __eq__(self, *args, **kwargs): # real signature unknown""" Return self==value. """passdef __getattribute__(self, *args, **kwargs): # real signature unknown""" Return getattr(self, name). """passdef __ge__(self, *args, **kwargs): # real signature unknown""" Return self>=value. """passdef __gt__(self, *args, **kwargs): # real signature unknown""" Return self>value. """passdef __iand__(self, *args, **kwargs): # real signature unknown""" Return self&=value. """passdef __init__(self, seq=()): # known special case of set.__init__"""set() -> new empty set objectset(iterable) -> new set objectBuild an unordered collection of unique elements.# (copied from class doc)"""passdef __ior__(self, *args, **kwargs): # real signature unknown""" Return self|=value. """passdef __isub__(self, *args, **kwargs): # real signature unknown""" Return self-=value. """passdef __iter__(self, *args, **kwargs): # real signature unknown""" Implement iter(self). """passdef __ixor__(self, *args, **kwargs): # real signature unknown""" Return self^=value. """passdef __len__(self, *args, **kwargs): # real signature unknown""" Return len(self). """passdef __le__(self, *args, **kwargs): # real signature unknown""" Return self<=value. """passdef __lt__(self, *args, **kwargs): # real signature unknown""" Return self<value. """pass@staticmethod # known case of __new__def __new__(*args, **kwargs): # real signature unknown""" Create and return a new object.  See help(type) for accurate signature. """passdef __ne__(self, *args, **kwargs): # real signature unknown""" Return self!=value. """passdef __or__(self, *args, **kwargs): # real signature unknown""" Return self|value. """passdef __rand__(self, *args, **kwargs): # real signature unknown""" Return value&self. """passdef __reduce__(self, *args, **kwargs): # real signature unknown""" Return state information for pickling. """passdef __repr__(self, *args, **kwargs): # real signature unknown""" Return repr(self). """passdef __ror__(self, *args, **kwargs): # real signature unknown""" Return value|self. """passdef __rsub__(self, *args, **kwargs): # real signature unknown""" Return value-self. """passdef __rxor__(self, *args, **kwargs): # real signature unknown""" Return value^self. """passdef __sizeof__(self): # real signature unknown; restored from __doc__""" S.__sizeof__() -> size of S in memory, in bytes """passdef __sub__(self, *args, **kwargs): # real signature unknown""" Return self-value. """passdef __xor__(self, *args, **kwargs): # real signature unknown""" Return self^value. """pass__hash__ = None

Set集合的源码

  添加: add( ), unions( )

  更新: difference_update( ), symmeteric_difference_update( ), intersection_update( ), update( )

  找不同: difference( ), symmeteric_difference( ),

  找相同: intersection( )

  删除: discard( ), remove( ), clear( ), pop( )

  返回Boolean值: isdisjoint( ), issuperset( )

  1. 添加: add()

    1 >>> se = set() #创建空集合
    2 >>> se
    3 set()
    4 >>> se.add(123) #添加123到集合里
    5 >>> se
    6 {123}

    集合功能:添加

  2. 清除所有在集合里的内容: clear()

    1 >>> se = set() #创建一个空集合
    2 >>> se.add(111)
    3 >>> se.add(222)
    4 >>> se.add(333)
    5 >>> print(se)
    6 {333, 222, 111}
    7 >>> se.clear() #清除集合里的所有元素
    8 >>> se
    9 set()

    集合功能:删除

  3. 对比两个集合,找其中一方的不同,相当于 database 里的 left outer join: difference()

     1 >>> s1 = {11,22,33}
     2 >>> s2 = {22,33,44}
     3 >>> s3 = s1.difference(s2) # 在s1中存在, s2中不存在
     4 >>> s1
     5 {33, 11, 22}
     6 >>> s3
     7 {11}
     8 >>> s3 = s2.difference(s1) #在s2中存在, s1中不存在
     9 >>> s3
    10 {44}

    集合功能:找不同

  4. 对比两个集合,取出双方不同的元素: symmetric_difference()

    1 >>> s1 = {11,22,33}
    2 >>> s2 = {22,33,44}
    3 >>> s3 = s1.symmetric_difference(s2) #找出双方都不存在的元素
    4 >>> s1
    5 {33, 11, 22}
    6 >>> s3
    7 {11, 44}

    集合功能:找不同

    更新: 对比两个集合,找其中一方的不同,然后直接把结果更新到原来的集合:difference_update()

    1 >>> a = {11,22,33}
    2 >>> b = {22,33,44}
    3 >>> a.difference_update(b) #对比两个集合,找其中一方的不同,然后直接把结果更新到原来的集合
    4 >>> a
    5 {11}

    集合功能:更新

  5. 更新: 对比两个集合,取出双方不同的元素,然后直接把结果更新到原来的集合:symmetric_difference_update()

    1 >>> a = {11,22,33}
    2 >>> b = {22,33,44}
    3 >>> a.symmetric_difference_update(b)
    4 >>> a
    5 {11, 44}

    集合功能:更新

  6. 刪除指定元素,不存在,不報錯!!discard()

    1 >>> s1 = {11,22,33}
    2 >>> s2 = {22,33,44}
    3 >>> s1.discard(11)
    4 >>> s1
    5 {33, 22}

    集合功能:删除

  7. 刪除指定元素,不存在,報錯!!!remove()

    1 >>> s1 = {11,22,33}
    2 >>> s2 = {22,33,44}
    3 >>> s1.remove(11)
    4 >>> s1
    5 {33, 22}
    6 >>> s1.remove(1111)
    7 Traceback (most recent call last):
    8   File "<stdin>", line 1, in <module>
    9 KeyError: 1111

    集合功能:删除

  8. 随机移取某个元素并获取这个元素: pop()

    1 >>> s1 = {11,22,33}
    2 >>> s2 = {22,33,44}
    3 >>> ret = s1.pop()
    4 >>> ret
    5 33

    集合功能:删除

  9. 对比两个集合,找双方交集部份,相当于 database 里的 inner join: intersection()

    1 >>> s1 = {11,22,33}
    2 >>> s2 = {22,33,44}
    3 >>> s3 = s1.intersection(s2) #找s1和s2相同的元素
    4 >>> s3
    5 {33, 22}
    6 >>> s1
    7 {33, 11, 22}

    集合功能:找相同

  10. 对比两个集合,找双方交集部份,相当于 database 里的 inner join,然后直接把结果更新到原来的集合:intersection_update()

    1 >>> s1 = {11,22,33}
    2 >>> s2 = {22,33,44}
    3 >>> s1.intersection_update(s2) #找相同然后直接更新 s1
    4 >>> s1
    5 {33, 22}

    集合功能:找相同然后更新

  11. 判断两个集合有没有交集部份,如果有便返回 False ;如果没有,则返回 True: isdisjoint()

    1 >>> s1 = {11,22,33}
    2 >>> s2 = {22,33,44}
    3 >>> s1.isdisjoint(s2) #有交集部分
    4 False
    5
    6 >>> s1 = {11,55,66}
    7 >>> s2 = {22,33,44}
    8 >>> s1.isdisjoint(s2) #没有交集部分
    9 True

    集合功能:返回Boolean值

  12. 判断两个集合有没有父子关系,有是 True, 沒有則 False: issuperset()

    1 >>> s1 = {11,22,33}
    2 >>> s2 = {22,33,44}
    3 >>> s1.issuperset(s2) #s1 不是 s2 的父序列
    4 False
    5 >>>
    6 >>> s1 = {11,22,33}
    7 >>> s2 = {22,33}
    8 >>> s1.issuperset(s2) #s1 是 s2 的父序列
    9 True

    集合功能:返回Boolean值

  13. 把两个集合连合然后去掉重覆的就是并集(这功能相当于 database, union 然后拿distinct value):union()

    1 >>> s1 = {11,22,33}
    2 >>> s2 = {22,33,44}
    3 >>> s3 = s1.union(s2)
    4 >>> s3
    5 {33, 22, 11, 44}

    集合功能:添加

  14. 批量地把一托集合增加到目标集合,update()接收一个可以被迭代的对象 e.g. List、Tuple、String:update()

    1 >>> s1 = {11,22,33}
    2 >>> s2 = {22,33,44}
    3 >>> s1.update({77,88,99})
    4 >>> s1
    5 {33, 99, 22, 88, 11, 77}
    6 >>> s1.update(s2)
    7 >>> s1
    8 {33, 99, 22, 88, 11, 44, 77}
    9 >>> 

    集合功能:更新

difference( ) 和 difference_update( ) 的应用:

  • s1 集合和 s2 集合的结果会保持不变,两个方法 difference() 和 symmetric_difference() 都会产生一个新的集合,所以在实际情景中如果需要重用 s1 和 s2 集合的时候,就不要用 differernce_updates() 和 symmetric_difference_update() 了。因为这两个函数会覆盖本來在 s1 里的结果。
  • 如果以后不需要基於 s1 來操作,只需要拿最新结果的话,就可以用 differernce_updates() 和 symmetric_difference_update(),这里的好处是变量声明减少了就可以​​节省内存空间! ! !

案例实战

[更新中...]

函数介紹和操作实战

在还没有学函数之前,我们实现的代码是用很多条件判断(If-then-else)还有表达式的For 循环来实现功能,不免有很多重覆性的代码,其实这个过程叫"面向过程编程”,就是从上到下按照逻辑一点一点去写,如果遇到重覆的功能,最典型的操作就是复制和粘贴(Copy and Paste)

面向过程编程的缺点:

  1. 如果代码量多的话,不断的复制和粘贴,会导致代码缺乏了可阅读性;
  2. 不断使用重覆代码,代码量多,程序员也会很累,会导致代码缺乏了重用性

**总结:基于以上两点的解决方安案是运用函数式编程!!函数是用来封装某些功能的,它的出现是为了增加代码的重用性,令代码更简洁,而且可以增加其可读性,以后如果要使用的话就直接调用这个函数就行啦! !

创建函数的步骤如下:

  1. def 关键字来声明这是一个函数;
  2. 在 def 後面加一個空格,然后寫上一個名字代表函数名稱,以后就可以在内存里调用它;
  3. 名字加上后再加一个括号 ( );
  4. 然后在函数体里写上函数的内容:就是具体需要实现的功能;
  5. 然后加上返回值,如果沒有返回值的話 Python 会有一个默应的返回值 (None)

    >>> def func():
    ...     print("123")
    ...
    >>> f1 = func()
    123
    >>> print("f1:",f1)
    f1: None

    沒有返回值

    有返回值的意思是:函数可以被調用然後賦值到另外一個參數,也就是說一個函数可以像參數一樣被传递。

    >>> def func():
    ...     return "123"
    ...
    >>> f1 = func()
    >>> print("f1:",f1)
    f1: 123

    有返回值

  6. 函数可以在括号里面输入参数。

案例实战

以下是一个发邮件的函数,把登录邮件和发邮件这个功能封装在一个叫 sendMail()的函数里,只要一调用这个功能,它就会运行同一样的代码来发送邮件,这就是函数。

def sendMail():import smtplibfrom email.mime.text import MIMETextfrom email.utils import formataddrmsg = MIMEText("Python Email testing",'plain','utf-8')msg['From'] = formataddr(["Janice", "janicecheng.python@gmail.com"])msg['To'] = formataddr(["Janice", "janicecheng.python@gmail.com"])msg['Subject']='主題'server = smtplib.SMTP("smtp.gmail.com", 587)server.starttls()server.login("janicecheng.python@gmail.com","password")server.sendmail("janicecheng.python@gmail.com",["janicecheng.python@gmail.com",], msg.as_string())print("Mail Send Successfully")server.quit()sendMail()

邮件发送函数代码

  • def sendMail( ): 这叫声明函数
  • sendMail( ): 这叫执行函数

     1 def sendMail():
     2
     3     import smtplib
     4     from email.mime.text import MIMEText
     5     from email.utils import formataddr
     6
     7     msg = MIMEText("Python Email testing",'plain','utf-8')
     8     msg['From'] = formataddr(["Janice", "janicecheng.python@gmail.com"])
     9     msg['To'] = formataddr(["Janice", "janicecheng.python@gmail.com"])
    10     msg['Subject']='主題'
    11
    12     server = smtplib.SMTP("smtp.gmail.com", 587)
    13     server.starttls()
    14     server.login("janicecheng.python@gmail.com","password")
    15     server.sendmail("janicecheng.python@gmail.com",["janicecheng.python@gmail.com",], msg.as_string())
    16
    17     print("Mail Send Successfully")
    18     server.quit()
    19
    20 sendMail()

    sendMail函数

注意:

  1. 当你在声明变量和函数之后,函数体在声明的时倏不会被执行的,它们分别会放在内存里,等待被调用!
  2. 在函数中一旦执行了 return, 函数的执行过程立即终止

返回值的补充说明

下面有一个例子,如果两个函数有相同的名称,然后在同一个程序里执行,运行结果会是多少呢?

以下是程序运行時的顺序:

  1. 第一步:Python 运行程序的时候是从上而下执行的,在 f1 声明函数放在内存的时候,它把1+2 声明后,然后放在内存里
  2. 第二步:当程序运行时碰到第2个 f1函数时,它再次在内存中把1x 2 放在内存中,并且 f1 指向 (1 x 2)
    • Python 有自己的垃圾回收机制,会定时把没有的变量或者函数删除掉。
  3. 第三步:声明一个变量把f1函数的返回值存储在里面
  4. 第四步:当调用 f1函数时,它实际上是运行 a1 * a2
  5. 第五步:然后实际运行 f1函数
  6. 第六步:打印出 ret 变量中的值

所以调用 f1函数时,它其实正在运行 a1 * a2的功能,这就是为什么答案会是 64的原因。

参数的深入介绍和操作实战

  1. 把参数传入然后在函数体里的内码块可以把这个参数当成变量的去使用,这种参数叫形式参数。当我们在调用程序的时候把参数传入然后执行,这种参数叫实际参数。在這個例子中,参数 target_email 叫形式参数;下面执行程序传入的 “Alex” 叫实际参数。
  2. 如果从内存的角度去看这两种参数的话,在调用sendmail( ) 然后传入“alex” 的时候,这个“alex” 的字符串就已经在内存中,这就相当于把“xxoo” 这个形式参数指向内存中的实际参数“alex”; 同样地;对于“eric” 这个实际参数,它在被调用的时候,”eric” 已经在内存中等待着,然后函数本身的形式参数就会指向“ eric ”,然后执行程序,这就是形式参数和实际参数的关系。
  3. 还有就是形式参数和实际参数的位置默认情况下是一一对应的
     
  4. 在Python中也可以定义默认参数,意思是在声明函数的时候,其中一些形式参数已经定义了一些默认值,注意:如果想要定义默认参数,必需把默认参数放在参数列表的最后位置! ! !

     1 #content="This is a testing email" 是默认参数
     2 def send(receipent,content="This is a testing email"):
     3     print("Email send to:",receipent,", Content:",content)
     4     print("Mail sent successfully")
     5     return True
     6
     7 send("janice@abc-company.com") # 默认 content 用了 "This is a testing email"
     8 send("janice@abc-company.com", "Company Notice") # content 用了 "Company Notice"
     9
    10 #Results:
    11 #Email send to: janice@abc-company.com , Content: This is a testing email
    12 #Mail sent successfully
    13 #Email send to: janice@abc-company.com , Content: Company Notice
    14 #Mail sent successfully

    默认参数

  5. 也可以声明指定参数,在调用的时候输入 “”形式参数=实际参数” e.g. content=“alex",这样就可以在函数被調用時忽略参数顺序。
  6. 对于动态参数有两种类: * 和 ** (分别是一个星号和两个星号)
    * 一个星号: 默认将传入的参数,全部放在一个元组中。 f1(*[11,22,33,44])
    ** 两个星号: 默认将传入的参数,全部放在一个字典中。 f1(**{"k1":"v1","k2":"v2”})

    动态参数 (*) 会返回一个元组,如果函数的形式参数有* 号就有特殊的功能 e.g. def f1(*args),就是按照顺序接受传入什么的值都会转换到元组里面,并且当做元组的一个元素;如果在传实际参数的时候加一個星 * 号 e.g. f1(*li),它的特殊的功能是将这个列表里的每一个元素都转化到元组的元素里,其实就相当于在内部​​做了一个 For 循环,把列表里的一个一个添加到元组里(Tuple)。

     1 def f3(*args):
     2     print(args) #返回一個元組
     3
     4 li = [11,22,"Janice","dfghjk"]
     5 name = "Janice"
     6
     7 f3(li)
     8 f3(*li)
     9 f3(*"Janice")
    10 f3(*name)
    11
    12 #Results:
    13 #([11, 22, 'Janice', 'dfghjk'],)
    14 #(11, 22, 'Janice', 'dfghjk')
    15 #('J', 'a', 'n', 'i', 'c', 'e')
    16 #('J', 'a', 'n', 'i', 'c', 'e')

    动态参数*

    动态参数 (**) 会返回一個字典,如果函数的形式参数有** 号就有特殊的功能 e.g. def f1(**args),就是传入什么的值都会转换到字典里面,并且当做字典value;如果在传实际参数的时候加上两个星** 号e.g. f1(**dic),它的特殊的功能是将这个字典里的每一个key, value 都给转化成字典的key, value,其实就相当于直接赋值到字典里。

     1 def f4(**args):
     2     print(args) #返回一個字典
     3
     4 li = [11,22,"Janice","dfghjk"]
     5 name = "Janice"
     6
     7 f4(n1="Janice")
     8 f4(n1="Janice", n2=20)
     9
    10 dic = {"k1":"v1","k2":"v2"}
    11 f4(kk = dic)
    12 f4(**dic)
    13
    14 #Results
    15 #{'n1': 'Janice'}
    16 #{'n1': 'Janice', 'n2': 20}
    17 #{'kk': {'k1': 'v1', 'k2': 'v2'}}
    18 #{'k1': 'v1', 'k2': 'v2'}

    动态参数**

  7. 万能参数,def f5(*args, **kwargs) (注意:* 一个星号必须在前面, ** 两个星号必须在后面!)

    1 def f5(*args, **kwargs):
    2     print(args)
    3     print(kwargs)
    4
    5 f5(11,22,33,44,k1="v1",k2="v2")
    6
    7 #Results:
    8 #(11, 22, 33, 44)
    9 #{'k2': 'v2', 'k1': 'v1'}

    万能参数*args, **kwargs

  8. 全局变量和局部变量
    没有写到函数体里的变量叫全局变量,它在所有文件中都是可读;在f1函数里写的变量是 f1函数私有的,叫局部变量;变量会先找自己的局部变量,然后才找全局变量,如果你想修改全局变量(重新赋值),这时需要加入一个global 的关键字+ 它的变量名。如果以后要读一个全局变量的时候,直接打印 e.g. print() 一下就可以啦!

    • 重点一、[列表, 字典, 元组] 如果在函数体里进行修改/新增, 这是在修改全区列表,但列表不容许在函数体里重新赋值。

    • 重点二、如果是全局变量,命名时都需要大写! ! !
  9. 补充:函数的参数在传入的时候,到底是传入引用还是再传入一份列表,現在来分析一下两种结果:

    1. 如果传入的是一份列表,Python 在传入参数的时候是重新赋值的话,打印的时候就不应该出现 999
    2. 如果传入的是一个引用, li 和 a1 便会指向同一个列表
    3. 從运行后的结果可以总结:Python 在传参数的时候,其实是传入一个引用! ! !

      1 def f7(a1):
      2     a1.append(9999)
      3
      4 li = [11,22,33,44]
      5 f7(li)
      6 print(li)
      7
      8 #Results:
      9 #[11, 22, 33, 44, 9999]

      运行后结果

实战操作

运用函数写一个简单的猜文字游戏

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Janice Chengimport os
import random
import sys# make a list of words
words = ['apple','banana','orange','coconuts','straweberry','lime','graphefruit','lemon','kumquat','blueberry','melon'
]def clear():if os.name == 'nt':os.system('cls')else:os.system("clear")def draw(bad_guess, good_guess, secret_word):clear()print("Strikes: {}/7".format(bad_guess))print('')for letter in bad_guess:print(letter, end=' ')print('\n\n')for letter in secret_word:if letter in good_guess:print(letter, end='')else:print('_', end='')print('')def get_guess(bad_guess, good_guess):while True:guess = input("Guess a letter: ").lower()if len(guess) != 1:print("You can only guess a single letter!")elif guess in bad_guess or guess in good_guess:print("You've already guess that letter")elif not guess.isalpha():print("You can only guess letters!")else:return guessdef play(done):clear()secret_word = random.choice(words)bad_guess = []good_guess = []while True:draw(bad_guess,good_guess,secret_word)guess = get_guess(bad_guess,good_guess)if guess in secret_word:good_guess.append(guess)found = Truefor letter in secret_word:if letter not in good_guess:found = Falseif found:print("You win!")print("The word was {}".format(secret_word))done = Trueelse:bad_guess.append(guess)if len(bad_guess) == 7:draw(bad_guess,good_guess, secret_word)print("You lost!")print("The word was {}".format(secret_word))done = Trueif done:play_again = input("Play again? y/n ").lower()if play_again != 'n':return play(done=False)else:sys.exit()def welcome():print("Welcome to Letter Guess!!")start = input("Press enter/return to start or Q to quit >> ").lower()if start == 'q':print('Bye!')sys.exit()else:return Trueif __name__ == "__main__":done = Falsewhile True:clear()welcome()play(done)

猜文字游戏

format 函数操作实战

ret = '{0} lives in Hong Kong for more than {1} years!!'.format('Janice',20)
ret = '{name} lives in Hong Kong for more than {year} years!!'.format(name='Janice', year=20)
# Janice lives in Hong Kong for more than 20 years!!

这是 Python format 函数的源码,它也是接受一个 *号的参数和 ** 两个星号的参数

    def format(self, *args, **kwargs): # known special case of str.format"""S.format(*args, **kwargs) -> strReturn a formatted version of S, using substitutions from args and kwargs.The substitutions are identified by braces ('{' and '}')."""pass

  1. 一个 *星号的函数例子

    >>> s = "My name is {} and I am {} years old".format("Janice",20)
    >>> s
    'My name is Janice and I am 20 years old'# 在参数里加入*便可以接受列表类型
    >>> s = "My name is {} and I am {} years old".format(*["Janice",20])
    >>> s
    'My name is Janice and I am 20 years old'# 这里不受列表类型
    >>> s = "My name is {} and I am {} years old".format(["Janice",20])
    Traceback (most recent call last):File "<stdin>", line 1, in <module>
    IndexError: tuple index out of range# 在括号里定义{0}和{1},就不需要在format()函数里重覆定义传递的内容
    >>> s = "My name is {0} and {0} and {0} I am {1} years old".format("Janice",20)
    >>> s
    'My name is Janice and Janice and Janice I am 20 years old'>>> s = "My name is {} and {} and {} I am {} years old".format("Janice",21)
    Traceback (most recent call last):File "<stdin>", line 1, in <module>
    IndexError: tuple index out of range

    一个*星号的函数

  2. 两个** 星号的函数例子

    1 >>> s = "My name is {name} and I am {age} years old".format(name="Janice",age=20)
    2 >>> s
    3
    4 >>> s = "My name is {name} and I am {age} years old".format(**{"name":"Janice","age":20}) # 在参数里加入**便可以接受字典类型
    5 >>> s
    6 'My name is Janice and I am 20 years old'

    两个**星号的函数

实战操作

运用函数式编程来进行登录或注册实战

[更新中...]

lambda 表达式介绍

这是一个简单的函数: f1(a) = a + 100

>>> def f1(a):
...     return a + 100
...
>>> ret = f1(10)
>>> print(ret)
110

普通函数

lambda a: a + 100
# a + 100 是函数体,a 是变量,整句意思是输入参数 a,然后对a进行操作:a + 100

就以上的代码,可以用 lambda 表达式来实现

>>> f2 = lambda a: a + 100 #自动返回
>>> ret2 = f2(10)
>>> print(ret2)
100

lambda 表达式例子一

>>> add = lambda a1,a2: a1 + a2 #可以传两个参数
>>> add(10,10)
20

lambda 表达式例子二

lambda 中的 filter 例子

>>> lst = [11,22,33,44]#Option1
>>> def f(x):
...     return x > 22>>> list(filter(f, lst))
[33, 44]#Option2
>>> list(filter(lambda a: a > 22, lst))
[33, 44]

lambda 表达式例子三

lambda 中的 map 例子

>>> lst1 = [1,3,5,6,9]
>>> lst2 = [2,4,6,8,10]
>>> ret = map(lambda x,y: x+y, lst1, lst2)
>>> list(ret)
[3, 7, 11, 14, 19]

lambda 表达式例子四

大家都应该听过 Spark,在 Spark 里用了很多 lambda 表达式来实现 filter、map、flatMap 和 reduceByKey 的功能,以下是一個 Spark 的 wordcount 例子

wordCounts = textFile.flatMap(lambda line: line.split())\.map(lambda word: (word, 1))\.reduceByKey(lambda a, b: a+b)

文件操作函数介紹和操作实战

打開文件

##Operation
output = open(r'C:\spam', 'w') #Create output file ('w' means write)
input = open('data', 'r') #Create input file ('r' means read)
input = open('data') #Same as prior line ('r' is the default)
open('f.txt', encoding='latin-1') #Python 3.X Unicode text files (str strings)
open('f.bin', 'rb') #Python 3.X bytes files (bytes strings)
open('f.bin', 'rb') #Python 2.X bytes files (str strings)
for line in open('data'): #File iterators read line by line

操作文件

##Method
aString = input.read() #Read entire file into a single string
aString = input.read(N) #Read up to nextNcharacters (or bytes) into a string
aString = input.readline() #Read next line (including\nnewline) into a string
aList = input.readlines() #Read entire file into list of line strings (with \n)
output.write(aString) #Write a string of characters (or bytes) into file
output.writelines(aList) #Write all line strings in a list into file
output.close() #Manual close (done for you when file is collected)
output.flush() #Flush output buffer to disk without closing
anyFile.seek(N) #Change file position to offsetNfor next operation

文件的打开方式不同就会对文件产生不同的影响,打开方式有几种:1) 以字符串类型读写文件; 2) 有加号的方式读写文件; 3) 以二进制(字节)类型读写文件;

# Remember to close the file after every file modification
f = open("readme.txt",'w') #open a file for writing
f.write("this is the first line\n") #write a line to the file
f.write("this is the second line\n") #write one more line to the file
f.close() #close a file

f = open("readme.txt",'r') #open a file for reading
f.read() # read the entire content of file at once
f.read(1) # read 1 char from the file
f.seek(1) # 调整指针到第一个位置
f.tell()
f.readable() # 是否是可读文件
f.readlines() # reading all lines as an array
f.readlines() # read only one line
f.close() #close a file

f = open("readme.txt",'a') #append data to the original file
f.write("this is the third line\n") #write a line to the file
f.close() #close a file

文件操作

以字符串类型打开:

  1. Append: "a" - 以追加的方式打开文件,(打开文件后的文件指针会自动移到文件末尾) 如果文件不存在则创建

    f = open("db","a")
    f.write("Python")
    f.close()#Before: admin|123
    #After: admin|123Python

    Append:a

  2. Read: "r" - 以读的方式打开文件,可读取文件信息

    1 >>> f2 = open("db","r")
    2 >>> data2 = f2.read()
    3 >>> print(data2)
    4 Admin|123
    5 Alex|alex3417
    6 >>> print(type(data2))
    7 <class 'str'>

    Read:r

  3. Write: "w" - 以写的方式打开文件,如果文件存在,则清空该文件,再重新写入新内容

    1 >>> import csv
    2 >>> f2 = open("db","w")
    3 >>> data = "admin|123"
    4 >>> f2.write(data)
    5 9
    6 >>> f2.close()

    Write:w

  4. Extend: "x" - 如果这个文件存在就报错,如果不存在就创建并写内容 (跟 w 是一样的,只增加多一个条件判断,判断一下当前文件是否已经存在)

     1 >>> f2 = open("db","x") #如果文件已经存在,你会报错
     2 Traceback (most recent call last):
     3   File "<stdin>", line 1, in <module>
     4 FileExistsError: [Errno 17] File exists: 'db'
     5
     6 >>> f2 = open("db_test","x")
     7 >>> data = "admin|123"
     8 >>> f2.write(data)
     9 9
    10 >>> f2.close()

    Extend:x

有+號的打開模式

  1. Append: "a+" - 以读写方式打开文件,并把文件指针移到文件尾
  2. Read: "r+" - 以读写方式打开文件,可以对文件进行读写操作,Python 在读完整个文件的时候,默认指针位置会在文件的末位​​,所以当 f.write("9999") 的时候,就会在文件最后的位置追加,所以如果用 "r" 打开时,可以配合 seek() 来指定写入的位置 (看下面seek()的例子)。

     1 >>> f = open("db","r+", encoding='utf-8')
     2 >>> data = f.read()
     3 >>> print(data)
     4 admin|123
     5 >>> f.write("9999")
     6 11
     7 >>> f.close()
     8
     9 #Results:
    10 #Before: admin|123
    11 #After: admin|1239999

    Read:r+

  3. Write: "w+" - 清除文件内容、然后以读写方式打开文件。可读可写,但會先清空,後再寫。

以二进制(字节)类型打开

  1. Append: "ab" - 如果使用二进制的方式写,必需也得传入字节类型

    1 >>> f = open("db","ab")
    2 >>> f.write(bytes("Python", encoding='utf-8'))
    3 6
    4 >>> f.close()
    5
    6 #Results:
    7 #Before: admin|123
    8 #After: admin|123Python

    Append:ab

    如果使用二进制的方式去写数据,但传入的是一个字符串,这时候程序就会报错!

    1 >>> f3 = open("db","ab") #如果加b只能写入字节
    2 >>> f3.write("hello")
    3 Traceback (most recent call last):
    4   File "<stdin>", line 1, in <module>
    5 TypeError: a bytes-like object is required, not 'str'

    Append:ab

  2. Read: "rb" - 只读,在读文件时自己去跟Python 底层的二进制沟通,你读的时候是读二进制,所以写的时候也需要写上二进制(字节),在硬盘上存储的是二进制格式,Python 在读的时候,默认把底层的二进制字节转转换成字符串,所以打印出来才会是字符串。

    1 >>> f1 = open("db","rb")
    2 >>> data1 = f1.read()
    3 >>> print(data1)
    4 b'Admin|123\nAlex|alex3417'
    5 >>> print(type(data1))
    6 <class 'bytes'>

    Read:rb

    **注意: encoding 这个参数,它是 Python 在把字节转化成字符串设定的一个编码,Python 会按照这个编码帮我们转换。意思就是说你用什么编码去存储文件(写)的同时,也应该用相同的编码去打开(读)文件。如果把 b 取掉读到的就是字符串类型,所以如果在打开文件的时候出现乱码,很大可能是这个 encoding 出现问题。

    f=open("db","r",encoding="GBK")

  3. Write: "wb"

文件操作的功能

  1. seek( ): 主动调整指针的位置,指针跳到指定位置 (永远以字符的方式找位置)

     1 >>> f = open("db","r+")
     2 >>> data = f.read(1)
     3 >>> print(data)
     4 a
     5 >>> f.seek(1) #调整指针到第一个位置
     6 1
     7 >>> f.write("999") #当前指针位置开始向后覆盖,写数据,打开方式有 b 、只能写字节;无b就是写字符
     8 3
     9 >>> f.close()
    10
    11 #Results:
    12 #Before: #admin|123
    13 #After: #a999n|123

    seek()

  2. tell( ): 获取当前指针的位置(字节),因為一個中文是3個字節,所以當調用read(1)方法之後,再查看當前字節位置,就會返回3

    1 >>> f = open("db","r+")
    2 >>> data = f.read(1)
    3 >>> print(data)
    4 金
    5 >>> print(f.tell())
    6 3
    7
    8 #db: 金|123

    tell()

  3. read( ): 默认无参数,读全部,如果在打开文件的时候是"rb",读取的时候会按字节;如果在打开文件的时候是"r",读取的时候会按字符。

     1 >>> f = open("db","rb")
     2 >>> data = f.read(1)
     3 >>> print(data)
     4 b'\xe9'
     5 >>> f.close()
     6 >>> f = open("db","r+")
     7 >>> data = f.read(1)
     8 >>> print(data)
     9 金
    10 >>> f.close()

    read()

  4. write( ): 写数据,如果在打开文件的时候是"rb",读取的时候会按字节;如果在打开文件的时候是"r",读取的时候会按字符。
  5. close( ):
  6. fileno( ):
  7. flush( ): 刷新,在文件还没有close()之前,f.write 的数据会存放在内存里而不直接写入文件,如果用了flush()的话,它就会在文件还没有调用close()的状况下强行把数据写入文件中。

    1 >>> f = open("db","a")
    2 >>> f.write("888")
    3 3
    4 >>>
    5 >>> input("Please input a number: ") #等待着用户输入
    6 Please input a number: 

    flush()

  8. readable( ): 判断是否可读

    1 >>> f2 = open("db_test","w")
    2 >>> f2.readable()
    3 False
    4 >>> f1 = open("db_test","r")
    5 >>> f1.readable()
    6 True

    readable()

  9. seekable( ):
  10. readline( ): 只读取一行(读取的过程指针会在移动)

     1 db.txt
     2 admin|123
     3 janice|janice123
     4 alex|alex123
     5 kennith|ken123
     6
     7 >>> f1 = open("db","r")
     8 >>> f1.readline()
     9 'admin|123\n'
    10 >>> f1.readline()
    11 'janice|janice123\n'
    12 >>> f1.close()

    readline()

  11. truncate( ):截断数据,只把指针位置后的清空

    1 f = open("db","r+",encoding='utf-8')
    2 f.seek(3)
    3 f.truncate()
    4 f.close()
    5
    6 #admin|123
    7 #adm

    truncate()

  12. for-loop:

     1 f = open("db","r+",encoding='utf-8')
     2 for line in f:
     3     print(line)
     4
     5
     6 f.close()
     7
     8 #admin|123
     9 #alex|alex3417
    10 #kennith|ken3344

    for-loop

關閉文件

  1. close( )

    f = close()

  2. with 文件操作

    1 with open("db","r+", encoding='utf-8') as f:
    2     for line in f:
    3         print(line)
    4
    5 #admin|123
    6 #alex|alex3417
    7 #kennith|ken3344

    with f1

  3. with 同時操作兩個文件

    1 #從db1文件一个以只读的方法打开,從db2文件一个以只写的方法打开
    2 #从DB1读一行写一行到DB2
    3 with open("db1","r", encoding='utf-8') as f1, open("db2","w", encoding='utf-8') as f2:
    4     for line in f1:
    5         new_line = line.replace("alex","eric")
    6         f2.write(new_line)

    with f1, f2

gzip

>>> import gzip
>>> with gzip.open('score.csv.gz','rt') as f:
...     print(f.read())
...
chinese,88
english,90
maths,85
computer science,90
chemistry,67
music,88
economics,75

gzip

本周作业

操作 haproxy.conf 文件

 1 global
 2         log 127.0.0.1 local2
 3         daemon
 4         maxconn 256
 5         log 127.0.0.1 local2 info
 6 defaults
 7         log global
 8         mode http
 9         timeout connect 5000ms
10         timeout client 50000ms
11         timeout server 50000ms
12         option  dontlognull
13 listen stats :8888
14         stats enable
15         stats uri       /admin
16         stats auth      admin:1234
17 frontend oldboy.org
18         bind 0.0.0.0:80
19         option httplog
20         option httpclose
21         option  forwardfor
22         log global
23         acl www hdr_reg(host) -i www.oldboy.org
24         use_backend www.oldboy.org if www
25 backend www.oldboy.org
26         server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000
27 backend buy.oldboy.org
28         server 100.1.7.90 100.1.7.90 weight 20 maxconn 3000

haproxy.cof

参考资料

金角大王:Python之路,Day3 - Python基础3

银角大王:Python开发【第四篇】:Python基础之函数

转载于:https://www.cnblogs.com/jcchoiling/p/5814704.html

第三章:Python基础の函数和文件操作实战相关推荐

  1. python身份证区域分割_python文件操作实战(将数据按照区域进行划分--身份证号...

    本篇包括14章内容,系统介绍了Python语言的基础知识.内容包括Python基础语法.数据类型和类型转换.运算符.流程控制(分支结构循环结构).数据结构(列表生成式).函数的定义及使用.异常处理.迭 ...

  2. 第三章 Python基础——文件操作函数

    3.1三元运算 三元运算又称三目运算,是对简单条件的简写 if 条件成立:val=1 else:val=2 改成三元运算: val=1 if条件成立 else 2 3.2字符编码转换 编码的种类情况: ...

  3. python基础3之文件操作、字符编码解码、函数介绍

    内容概要: 一.文件操作 二.字符编码解码 三.函数介绍 一.文件操作 文件操作流程: 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 基本操作: 1 #/usr/bin/e ...

  4. Python基础7:文件操作

    [ 文件操作] 1 对文件操作流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 现有文件如下: 昨夜寒蛩不住鸣. 惊回千里梦,已三更. 起来独自绕阶行. 人悄悄,帘外月胧 ...

  5. Python基础知识_day10_文件操作_pickle模块_os模块_shutil模块

    文章目录 1. 文本文件和二进制文件 2. 创建文件对象 open() 3. 文本文件的写入 3.1 write()/writelines()写入数据 3.2 with语句 4. 文本文件的读取 5. ...

  6. 第三章 Python基础知识

    list1 = ['张三','男',33,'江苏','硕士','已婚',['身高178','体重72']] # 取出第一个元素 print(list1[0]) # 取出第四个元素 print(list ...

  7. 第三章 python基础

    字符串 字符串:由0个或多个字符组成的有序字符序列 字符串由一对单引号或一对双引号表示 字符串是字符的有序序列,可以对其中的字符进行索引 "hello"---->h e l ...

  8. python基础之写文件操作

    博主简介:原互联网大厂tencent员工,网安巨头Venustech员工,阿里云开发社区专家博主,微信公众号java基础笔记优质创作者,csdn优质创作博主,创业者,知识共享者,欢迎关注,点赞,收藏. ...

  9. 简单 Python 快乐之旅之:Python 基础语法之文件操作专题

    文章目录 1. 读取文本文件 1.1. 读取文本文件里的个别字符 1.2. 以文本模式读取文件 2. 向文本文件写入字符串 2.1. 将字符串写入文本文件 2.2. 在文本模式下将字符串写入文本文件 ...

最新文章

  1. TensorFlow+TVM优化NMT神经机器翻译
  2. NSString属性什么时候用copy,什么时候用strong?
  3. 珠海市建设工程质量监督检测站
  4. 创立一家互联网公司,需要几步?
  5. python定时器 是线程吗_python线程定时器Timer(32)
  6. DevExpress的图形按钮菜单栏控件WindowsUIButtonPanel的布局、使用和设置按钮的点击事件
  7. XFtp中文乱码解决
  8. 利用kinect检测任意平面
  9. 2021-2022元宇宙报告:化身与智造,元宇宙座标解析
  10. linux 升级内核为4.10,Linux Kernel 4.10.4 发布下载
  11. UVA 12300 Smallest Regular Polygon(正多边形)
  12. golang 建立web服务器 http包源码详解
  13. Iocomp控件 Iocomp安装教程 Crack 下载
  14. 黑色精美大气DJ音乐歌曲网站源码+带WAP手机端
  15. 字节跳动Java大数据工程师面试题、笔试题(含答案)
  16. html excel 2位小数,excel保留两位小数_excel用公式保留2位小数的方法
  17. Redux-前端开发者的福音
  18. 数据分析之numpy基础/matplotlib绘图/numpy常用函数/杂项功能
  19. 【3C认证】儿童安全座椅3C认证本年9月1日起实施
  20. JavaScript之延迟加载

热门文章

  1. python教程哪个版本好-tensorflow用python哪个版本更好?
  2. 学好python能干嘛-python都能做什么
  3. python爬虫实例-Python爬虫案例集合
  4. python编程培训多少钱-想要学习Python,武汉Python编程培训费用是多少?
  5. 零基础学python需要多久-零基础学Python要多久
  6. 学python入门书-如何学习Python,以及新手如何入门?
  7. python官网下载步骤linux-linux 安装 python 最全教程
  8. python免费视频-Python免费视频教程
  9. python批量读取文件夹中的所有excel文件-python遍历文件夹下所有excel文件
  10. python和c++哪个好找工作-Scratch和Python与C++选哪个合适