文章目录
前言
接续上一章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')]