Python学习进阶——Part1

2-1 迭代器与生成器

  • 迭代器是一个可以记住遍历的位置的对象。

  • 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

  • 迭代器有两个基本的方法:iter()next()

  • 字符串,列表或元组对象都可用于创建迭代器

  • # e.g.1
    >>> list=[1,2,3,4]
    >>> it = iter(list)    # 创建迭代器对象
    >>> print (next(it))   # 输出迭代器的下一个元素
    1
    >>> print (next(it))
    2
    
    # e.g.2
    list=[1,2,3,4]
    it = iter(list)    # 创建迭代器对象
    for x in it:
        print (x, end=" ")
        
    # e.g.3
    import sys         # 引入 sys 模块
     
    list=[1,2,3,4]
    it = iter(list)    # 创建迭代器对象
     
    while True:
        try:
            print (next(it))
        except StopIteration:
            sys.exit()
    

1. 迭代器的创建

  • 把一个类作为一个迭代器使用需要在类中实现两个方法 iter() 与 next() 。

    • iter() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 next() 方法并通过 StopIteration 异常标识迭代的完成。
    • next() 方法(Python 2 里是 next())会返回下一个迭代器对象。
  • e.g.

    • class MyNumbers:
        def __iter__(self):
          self.a = 1
          return self
       
        def __next__(self):
          x = self.a
          self.a += 1
          return x
       
      myclass = MyNumbers()
      myiter = iter(myclass)
       
      print(next(myiter))
      print(next(myiter))
      print(next(myiter))
      print(next(myiter))
      print(next(myiter))
      

2. Stoplteration

  • StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 next() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。

  • e.g.

    • class MyNumbers:
        def __iter__(self):
          self.a = 1
          return self
       
        def __next__(self):
          if self.a <= 20:
            x = self.a
            self.a += 1
            return x
          else:
            raise StopIteration
       
      myclass = MyNumbers()
      myiter = iter(myclass)
       
      for x in myiter:
        print(x)
      

3. 生成器

  • 在 Python 中,使用了 yield 的函数被称为生成器(generator)。

  • 跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

  • 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

  • 调用一个生成器函数,返回的是一个迭代器对象。

  • e.g.

    • import sys
       
      def fibonacci(n): # 生成器函数 - 斐波那契
          a, b, counter = 0, 1, 0
          while True:
              if (counter > n): 
                  return
              yield a
              a, b = b, a + b
              counter += 1
      f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
       
      while True:
          try:
              print (next(f), end=" ")
          except StopIteration:
              sys.exit()
      

2-2 函数

  • 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段

1. 函数的定义

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fvETP2pE-1650542060741)(https://s2.loli.net/2022/04/17/f6EiymW8zvxIBer.png)]

规则:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()
  • 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
  • 函数内容以冒号 : 起始,并且缩进。
  • return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。

语法:

def 函数名(参数列表):
    函数体

2. 参数传递

python 函数的参数传递:

  • **不可变类型:**类似 C++ 的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。
  • **可变类型:**类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响

3. 参数

以下是调用函数时可使用的正式参数类型:

  • 必需参数、关键字参数、默认参数、不定长参数

1)必须参数

  • 必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
#可写函数说明
def printme( str ):
   "打印任何传入的字符串"
   print (str)
   return
 
# 调用 printme 函数,不加参数会报错
printme()

2) 关键字参数

  • 关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
  • 使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
#可写函数说明
def printinfo( name, age ):
   "打印任何传入的字符串"
   print ("名字: ", name)
   print ("年龄: ", age)
   return
 
#调用printinfo函数
printinfo( age=50, name="runoob" )

3) 默认参数

  • 调用函数时,如果没有传递参数,则会使用默认参数。
#可写函数说明
def printinfo( name, age = 35 ):
   "打印任何传入的字符串"
   print ("名字: ", name)
   print ("年龄: ", age)
   return
 
#调用printinfo函数
printinfo( age=50, name="runoob" )
print ("------------------------")
printinfo( name="runoob" )

4) 不定长参数

  • 你可能需要一个函数能处理比当初声明时更多的参数。
  • 加了星号 ***** 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。
# 可写函数说明
def printinfo( arg1, *vartuple ):
   "打印任何传入的参数"
   print ("输出: ")
   print (arg1)
   print (vartuple)
 
# 调用printinfo 函数
printinfo( 70, 60, 50 )

输出: 
70
(60, 50)
  • 还有一种就是参数带两个星号 **,参数会以字典的形式导入。
# 可写函数说明
def printinfo( arg1, **vardict ):
   "打印任何传入的参数"
   print ("输出: ")
   print (arg1)
   print (vardict)
 
# 调用printinfo 函数
printinfo(1, a=2,b=3)

输出: 
1
{'a': 2, 'b': 3}
  • 声明函数时,参数中星号 ***** 可以单独出现,后参数要求为关键字形参
def f(a,b,*,c):
     return a+b+c 
f(1,2,3)

# 报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 3 were given
    
    
f(1,2,c=3) # 正常

输出:
6

5)匿名函数

Python 使用 lambda 来创建匿名函数。

所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。

  • lambda 只是一个表达式,函数体比 def 简单很多。
  • lambda 的主体是一个表达式,而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去。
  • lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
  • 虽然 lambda 函数看起来只能写一行,却不等同于 C 或 C++ 的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
# 语法
lambda [arg1 [,arg2,.....argn]]:expression

# e.g.1
x = lambda a : a + 10
print(x(5))

输出
15

# e.g.2
# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2
 
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))

输出
相加后的值为 :  30
相加后的值为 :  40
  • 可以将匿名函数封装在一个函数内,这样可以使用同样的代码来创建多个匿名函数。
def myfunc(n):
  return lambda a : a * n
 
mydoubler = myfunc(2)
mytripler = myfunc(3)
 
print(mydoubler(11))
print(mytripler(11))

输出
22
33

6) 强制位置参数

Python3.8 新增了一个函数形参语法 / 用来指明函数形参必须使用指定位置参数,不能使用关键字参数的形式。

在以下的例子中,形参 a 和 b 必须使用指定位置参数,c 或 d 可以是位置形参或关键字形参,而 e 和 f 要求为关键字形参:

def f(a, b, /, c, d, *, e, f):
    print(a, b, c, d, e, f)
    
正确:
f(10, 20, 30, d=40, e=50, f=60)

错误:
f(10, b=20, c=30, d=40, e=50, f=60)
	# b 不能使用关键字参数的形式 
f(10, 20, 30, 40, 50, f=60) 
	# e 必须使用关键字参数的形式

2-3 输入和输出

1. 输出格式美化

1) str()

  • str(): 函数返回一个用户易读的表达形式。
>>> str(1/7)
'0.14285714285714285'

2) repr()

  • repr(): 产生一个解释器易读的表达形式。

  • >>> s = 'Hello, Runoob'
    >>> repr(s)
    "'Hello, Runoob'"
    
    >>> #  repr() 函数可以转义字符串中的特殊字符
    ... hello = 'hello, runoob\n'
    >>> hellos = repr(hello)
    >>> print(hellos)
    'hello, runoob\n'
    
    >>> # repr() 的参数可以是 Python 的任何对象
    ... repr((x, y, ('Google', 'Runoob')))
    "(32.5, 40000, ('Google', 'Runoob'))"
    

3)just() / zfill()

  • rjust() / ljust() / center()
    • 字符串靠右/左/居中, 并在填充空格对齐
  • zfill()
    • 在数字的左边填充 0

4) str.format()

>>> print('{1} 和 {0}'.format('Google', 'Runoob'))
Runoob 和 Google

>>> print('站点列表 {0}, {1}, 和 {other}。'.format('Google', 'Runoob', other='Taobao'))
站点列表 Google, Runoob, 和 Taobao。

# !a (使用 ascii()), !s (使用 str()) 和 !r (使用 repr()) 可以用于在格式化某个值之前对其进行转化
>>> print('常量 PI 的值近似为: {}。'.format(math.pi))
常量 PI 的值近似为: 3.141592653589793>>> print('常量 PI 的值近似为: {!r}。'.format(math.pi))
常量 PI 的值近似为: 3.141592653589793# 在 : 后传入一个整数, 可以保证该域至少有这么多的宽度
>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
>>> for name, number in table.items():
...     print('{0:10} ==> {1:10d}'.format(name, number))
...
Google     ==>          1
Runoob     ==>          2
Taobao     ==>          3
  • 如果你有一个很长的格式化字符串, 而你不想将它们分开, 那么在格式化时通过变量名而非位置会是很好的事情。

    • # 最简单的就是传入一个字典, 然后使用方括号 [] 来访问键值 :
      >>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
      >>> print('Runoob: {0[Runoob]:d}; Google: {0[Google]:d}; Taobao: {0[Taobao]:d}'.format(table))
      Runoob: 2; Google: 1; Taobao: 3
      # 也可以通过在 table 变量前使用 ** 来实现相同的功能:
      >>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
      >>> print('Runoob: {Runoob:d}; Google: {Google:d}; Taobao: {Taobao:d}'.format(**table))
      Runoob: 2; Google: 1; Taobao: 3
      

5) 旧式字符串格式化

  • % 操作符也可以实现字符串格式化。 它将左边的参数作为类似 sprintf() 式的格式化字符串, 而将右边的代入, 然后返回格式化后的字符串
>>> print('常量 PI 的值近似为:%5.3f。' % math.pi)
常量 PI 的值近似为:3.142

2. 读取键盘输入

  • Python 提供了 input() 内置函数从标准输入读入一行文本,默认的标准输入是键盘
str = input("请输入:");
print ("你输入的内容是: ", str)

请输入:Python学习
你输入的内容是:  Python学习
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bayyys

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值