python基础第二章:流程控制

前言

接续上一章python基础知识python基础第一章:基本语法和运算,第二章主要是流程控制。

一、选择语句if

if 语句包含零个或多个 elif 子句,及可选的 else 子句。关键字 ‘elif’ 是 ‘else if’ 的缩写,适用于避免过多的缩进。

x=int(input("please input an integer"))
if x<0:
    print("x<0")
elif x==0:
    print("zero")
elif x>0:
    print("x>0")
else:
    print("more")

二、循环语句for

1、功能:Python 的 for 语句不迭代算术递增数值(如 Pascal),或是给予用户定义迭代步骤和暂停条件的能力(如 C),而是迭代列表或字符串等任意序列,元素的迭代顺序与在序列中出现的顺序一致。
示例:

word=["cat","dog","elephant"]
for i in word:
    print(i,len(i))

输出结果:

cat 3
dog 3
elephant 8

注意:遍历某个集合的同时修改该集合的内容,很难获取想要的结果。要在遍历时修改集合的内容,应该遍历该集合的副本或创建新的集合:
(1)遍历副本

# Strategy:  Iterate over a copy
for user, status in users.copy().items():
    if status == 'inactive':
        del users[user]

(2)创建新集合

# Strategy:  Create a new collection
active_users = {}
for user, status in users.items():
    if status == 'active':
        active_users[user] = status

2、循环中的 break、continue 语句及 else 子句
(1)break:break 语句和 C 中的类似,用于跳出最近的 for 或 while 循环
(2)else:
循环语句支持 else 子句;for 循环中,可迭代对象中的元素全部循环完毕时,或 while 循环的条件为假时,执行该子句;break 语句终止循环时,不执行该子句。

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print(n, 'equals', x, '*', n//x)
            break
    else:
        # loop fell through without finding a factor
        print(n, 'is a prime number')

输出结果:

2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

(3)continue:continue 语句也借鉴自 C 语言,表示继续执行循环的下一次迭代

三、range()函数

1、range() 常用于遍历数字序列,该函数可以生成算术级数

for i in range(5):
    print(i)

2、步长:
range 可以不从 0 开始,还可以按指定幅度递增(递增幅度称为 ‘步进’,支持负数)

>>> list(range(5, 10))
[5, 6, 7, 8, 9]

>>> list(range(0, 10, 3))
[0, 3, 6, 9]

>>> list(range(-10, -100, -30))
[-10, -40, -70]

3、按索引迭代序列

>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
...     print(i, a[i])
...
0 Mary
1 had
2 a
3 little
4 lamb

四、循环

4.1字典中的循环

在字典中循环时,用 items() 方法可同时取出键和对应的值:

temp={'1':'first','2':'second'}
for k,v in temp.items():
    print(k,v)

输出结果:

1 first
2 second

4.2序列中的循环

在序列中循环时,用 enumerate() 函数可以同时取出位置索引和对应的值

#序列遍历
temp1=["a","b","c"]
for i,v in enumerate(temp1):
    print(i,v);

输出结果

0 a
1 b
2 c

4.3循环两个或多个序列

同时循环两个或多个序列时,用 zip() 函数可以将其内的元素一一匹配

>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
...     print('What is your {0}?  It is {1}.'.format(q, a))
...
What is your name?  It is lancelot.
What is your quest?  It is the holy grail.
What is your favorite color?  It is blue.

4.4逆向循环序列

逆向循环序列时,先正向定位序列,然后调用 reversed() 函数:

>>> for i in reversed(range(1, 10, 2)):
...     print(i)
...
9
7
5
3
1

4.5顺序序列循环

按指定顺序循环序列,可以用 sorted() 函数,在不改动原序列的基础上,返回一个重新的序列:

basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
for i in sorted(basket):
    print(i)

输出结果

apple
apple
banana
orange
orange
pear

4.6循环序列中唯一元素

使用 set() 去除序列中的重复元素。使用 sorted() 加 set() 则按排序后的顺序,循环遍历序列中的唯一元素

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
...     print(f)
...
apple
banana
orange
pear

五、函数

5.1函数定义

定义 函数使用关键字 def,后跟函数名与括号内的形参列表。函数语句从下一行开始,并且必须缩进。

def fib(n):    # write Fibonacci series up to n
    """Print a Fibonacci series up to n."""
    a, b = 0, 1
    while a < n:
        print(a, end=' ')
        a, b = b, a+b
    print()

# Now call the function we just defined:
fib(2000)

5.2默认值参数

为参数指定默认值是非常有用的方式。调用函数时,可以使用比定义时更少的参数,例如:

def ask_ok(prompt, retries=4, reminder='Please try again!'):
    while True:
        ok = input(prompt)
        if ok in ('y', 'ye', 'yes'):
            return True
        if ok in ('n', 'no', 'nop', 'nope'):
            return False
        retries = retries - 1
        if retries < 0:
            raise ValueError('invalid user response')
        print(reminder)

该函数可以用以下方式调用:

只给出必选实参:ask_ok('Do you really want to quit?')
给出一个可选实参:ask_ok('OK to overwrite the file?', 2)
给出所有实参:ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')

5.3关键字参数

1、关键字参数与位置参数对比;
在调用函数时传给 function (或 method )的值。参数分为两种:关键字参数和位置参数

(1)关键字参数: 在函数调用中前面带有标识符(例如 name=)或者作为包含在前面带有 ** 的字典里的值传入。举例来说,3 和 5 在以下对 complex() 的调用中均属于关键字参数:

complex(real=3, imag=5)
complex(**{'real': 3, 'imag': 5})

(2)位置参数:不属于关键字参数的参数。位置参数可出现于参数列表的开头以及/或者作为前面带有 * 的 iterable 里的元素被传入。举例来说,3 和 5 在以下调用中均属于位置参数:

complex(3, 5)
complex(*(3, 5))

2、关键字参数举例:

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
    print("-- This parrot wouldn't", action, end=' ')
    print("if you put", voltage, "volts through it.")
    print("-- Lovely plumage, the", type)
    print("-- It's", state, "!")

parrot(1000)                                          # 1 positional argument
parrot(voltage=1000)                                  # 1 keyword argument
parrot(voltage=1000000, action='VOOOOOM')             # 2 keyword arguments
parrot(action='VOOOOOM', voltage=1000000)             # 2 keyword arguments
parrot('a million', 'bereft of life', 'jump')         # 3 positional arguments
parrot('a thousand', state='pushing up the daisies')  # 1 positional, 1 keyword

3、注意事项:
(1)函数调用时,关键字参数必须跟在位置参数后面。
(2)所有传递的关键字参数都必须匹配一个函数接受的参数(比如,actor 不是函数 parrot 的有效参数),
(3)关键字参数的顺序并不重要。这也包括必选参数,(比如,parrot(voltage=1000) 也有效)。
(4)不能对同一个参数多次赋值.

parrot()                     # required argument missing
parrot(voltage=5.0, 'dead')  # non-keyword argument after a keyword argument
parrot(110, voltage=220)     # duplicate value for the same argument
parrot(actor='John Cleese')  # unknown keyword argument

5.4元祖和字典的参数传递

1、字典:最后一个形参为 **name 形式时,接收一个字典,该字典包含与函数中已定义形参对应之外的所有关键字参数
2、元祖: *name 形参接收一个 元组,该元组包含形参列表之外的位置参数
3、举例:
函数定义:

def cheeseshop(kind, *arguments, **keywords):
    print("-- Do you have any", kind, "?")
    print("-- I'm sorry, we're all out of", kind)
    for arg in arguments:
        print(arg)
    print("-" * 40)
    for kw in keywords:
        print(kw, ":", keywords[kw])

函数调用:

cheeseshop("Limburger", "It's very runny, sir.",
           "It's really very, VERY runny, sir.",
           shopkeeper="Michael Palin",
           client="John Cleese",
           sketch="Cheese Shop Sketch")

输出结果:

-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
shopkeeper : Michael Palin
client : John Cleese
sketch : Cheese Shop Sketch

5.5特殊参数

1、作用:为了让代码易读、高效,最好限制参数的传递方式,这样,开发者只需查看函数定义,即可确定参数项是仅按位置、按位置或关键字,还是仅按关键字传递。
2、格式:

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
      -----------    ----------     ----------
        |             |                  |
        |        Positional or keyword   |
        |                                - Keyword only
         -- Positional only

3、仅位置参数:
仅限位置形参应放在 / (正斜杠)前。/ 用于在逻辑上分割仅限位置形参与其它形参。如果函数定义中没有 /,则表示没有仅限位置形参。
4、仅关键字参数:
把形参标记为仅限关键字,表明必须以关键字参数形式传递该形参,应在参数列表中第一个 仅限关键字 形参前添加 *。
5、举例:
(1)第一个函数定义 standard_arg 是最常见的形式,对调用方式没有任何限制,可以按位置也可以按关键字传递参数:

def standard_arg(arg):
    print(arg)
>>> standard_arg(2)
2
>>> standard_arg(arg=2)
2

(2)第二个函数 pos_only_arg 的函数定义中有 /,仅限使用位置形参:

>>> def pos_only_arg(arg, /):
...     print(arg)
>>> pos_only_arg(1)
1
>>> pos_only_arg(arg=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: pos_only_arg() got an unexpected keyword argument 'arg'

(3)第三个函数 kwd_only_args 的函数定义通过 * 表明仅限关键字参数

>>> def kwd_only_arg(*, arg):
...     print(arg)

>>> kwd_only_arg(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given

>>> kwd_only_arg(arg=3)
3

(4)最后一个函数在同一个函数定义中,使用了全部三种调用惯例

>>> def combined_example(pos_only, /, standard, *, kwd_only):
...     print(pos_only, standard, kwd_only)

>>> combined_example(1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: combined_example() takes 2 positional arguments but 3 were given
>>> combined_example(1, 2, kwd_only=3)
1 2 3
>>> combined_example(1, standard=2, kwd_only=3)
1 2 3
>>> combined_example(pos_only=1, standard=2, kwd_only=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: combined_example() got an unexpected keyword argument 'pos_only'

6、位置参数在字典中的应用
下面的函数定义中,kwds 把 name 当作键,因此,可能与位置参数 name 产生潜在冲突:

def foo(name, **kwds):
    return 'name' in kwds

调用该函数不可能返回 True,因为关键字 ‘name’ 总与第一个形参绑定。例如:

>>> foo(1, **{'name': 2})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() got multiple values for argument 'name'
>>>

加上 / (仅限位置参数)后,就可以了。此时,函数定义把 name 当作位置参数,‘name’ 也可以作为关键字参数的键:

def foo(name, /, **kwds):
    return 'name' in kwds
>>> foo(1, **{'name': 2})
True

5.6任意实参列表

可变数量的参数包含在元组中。
在可变数量的实参之前,可能有若干个普通参数:

def write_multiple_items(file, separator, *args):
    file.write(separator.join(args))

*args 形参后的任何形式参数只能是仅限关键字参数,即只能用作关键字参数,不能用作位置参数:

>>> def concat(*args, sep="/"):
...     return sep.join(args)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'

5.7解包实参列表

函数调用要求独立的位置参数,但实参在列表或元组里时,要执行相反的操作。
元组和列表用*解包,字典用**解包
举例:

#列表
>>> list(range(3, 6))            # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args))            # call with arguments unpacked from a list
[3, 4, 5]
#字典
>>> def parrot(voltage, state='a stiff', action='voom'):
...     print("-- This parrot wouldn't", action, end=' ')
...     print("if you put", voltage, "volts through it.", end=' ')
...     print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

5.8Lambda 表达式

1、定义:lambda表达式是一行的函数。它们在其他语言中也被称为匿名函数。即函数没有具体的名称。
2、举例:

>>> def make_incrementor(n):
...     return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43

3、特殊Lambda表达式

>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> pairs.sort(key=lambda pair: pair[1])
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

oax_knud

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

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

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

打赏作者

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

抵扣说明:

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

余额充值