Python 学习笔记 - 第二天
1.if 语句
>>> x = int(input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
... x = 0
... print('Negative changed to zero')
... elif x == 0:
... print('Zero')
... elif x == 1:
... print('Single')
... else:
... print('More')
...
More
2.for 语句
类似 for-each
循环
>>> words = ['cat', 'window', 'defenestrate']
>>> for w in words:
... print(w, len(w))
...
cat 3
window 6
defenestrate 12
在迭代循环过程中, 不要去做可能修改序列尺寸的操作, 否则易导致奇怪的 bug.
如果需要做这种修改操作, 可以使用序列切片来做一个副本, 即可避免这种不安全的操作.
>>> for w in words[:]:
... if len(w) > 6:
... words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']
3.range() 函数
内置函数 range()
将生成一个等差级数链表
>>> for i in range(5):
... print(i)
...
0
1
2
3
4
range()
函数有三个参数, 第一个参数为起始值, 第二个参数为结束值(不包括在范围内), 第三个参数为步进值('步长').
>>> range(5, 10)
5 through 9
>>> range(0, 10, 3)
0, 3, 6, 9
>>> range(-10, -100, -30)
-10, -40, -70
如果迭代时要使用索引, 可以结合使用 range()
和 len()
(mark: 还有个 enumerate()
函数可以解决这种需求)
>>> 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
如果直接打印 range() 函数的话…
>>> print(range(10))
range(0, 10)
range() 是一个可迭代的对象.
使用 list()
函数可以迭代这个序列:
>>> list(range(5))
[0, 1, 2, 3, 4]
4.break 和 continue 语句, 以及循环中的 else
循环中的 else
表示在迭代完整个序列后(for) 或执行结果为 false (while) 时执行. 但循环被 break
中止的情况下不会执行这个 else
.
以下为搜索素数的示例:
>>> for n in range(2, 10):
... for x in range(2, n):
... if n % x == 0:
... print(n, 'equals', x, '*', n//x)
... break
... else:
... 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
break
、continue
语句和 C 、java 中的类似.
>>> for num in range(2, 10):
... if num % 2 == 0:
... print("Found an even number", num)
... continue
... print("Found a number", num)
...
Found an even number 2
Found a number 3
Found an even number 4
Found a number 5
Found an even number 6
Found a number 7
Found an even number 8
Found a number 9
5.pass 语句
pass
语句表示什么也不做.
>>> while True:
... pass
...
通常用于创建最小结构的类:
>>> class MyEmptyClass:
... pass
...
定义函数时
>>> def initlog(*args):
... pass # TODO
...
6.定义函数
关键字 def
引入了一个函数定义.
函数体的第一行语句可以是可选的字符串文本,这个字符串是函数的文档字符串,或者称为 docstring.
定义一个生成斐波那契数列的函数:
>>> def fib(n):
... """Print a Fibonacci series up to n."""
... a, b = 0, 1
... while a < n:
... print(a, end=' ')
... a, b = b, a+b
... print()
...
>>> fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
函数指向的地址值可以赋值给另一个名字, 这个名字也可以当作这个函数使用. 相当于重命名.
>>> fib
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89
没有 return
的函数默认也会返回一个值 None
.
>>> fib(0)
>>> print(fib(0))
None
定义一个返回斐波那契数列数字列表的函数:
>>> def fib2(n):
... """Return a list containing the Fibonacci series up to n."""
... result = []
... a, b = 0, 1
... while a < n:
... result.append(a) # see below
... a, b = b, a+b
... return result
...
>>> f100 = fib2(100)
>>> f100
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
6.1.默认参数
def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
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 OSError('uncooperative user')
print(complaint)
in
关键字, 测定序列中是否包含某个值.
该函数有几种调用方式:
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!')
默认值可以使用变量赋值, 但只被赋值一次. 当默认值为可变对象时, 例如列表、字典等, 默认值会随之变化而变化.
>>> def f(a, L=[]):
... L.append(a)
... return L
...
>>> print(f(1))
[1]
>>> print(f(2))
[1, 2]
>>> print(f(3))
[1, 2, 3]
如果你不想让默认值在后续调用中累积,你可以像下面一样定义函数:
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
6.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)
parrot(voltage=1000)
parrot(voltage=1000000, action='VOOOOOM')
parrot(action='VOOOOOM', voltage=1000000)
parrot('a million', 'bereft of life', 'jump')
parrot('a thousand', state='pushing up the daisies')
无效调用举例:
parrot()
# 没有传必选参数
parrot(voltage=5.0, 'dead')
# 在关键字参数后也必须用关键字传参数
parrot(110, voltage=220)
# 参数重复传递
parrot(actor='John Cleese')
# 未知参数名
可以使用 *name
来接收一个元组, 使用 **name
来接收一个字典. 并且 *name
必须在 **name
之前.
示例:
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)
keys = sorted(keywords.keys())
for kw in keys:
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.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch
sorted()
可以用来排序一个序列.
6.3.可变参数列表
使用元组来接收可变参数, 一般示例:
def write_multiple_items(file, separator, *args):
file.write(separator.join(args))
在可变参数之后, 只能使用关键字参数.
>>> def concat(*args, sep="/"):
... return sep.join(args)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'
6.4.参数列表的拆分
使用 *
将列表自动拆分成多个参数进行传递.
>>> list(range(3, 6))
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args))
[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 !
6.5.使用 Lambda 表达式.
>>> def make_incrementor(n):
... return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43
将 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')]
6.6.文档字符串
第一行是关于对象用途的简介, 以大学字母开头, 以句号结束.
如果有多行文档字符串, 第二行应该空出来, 第三行开始详细描述.
需要自行清除空白缩进.
示例:
>>> def my_function():
... """Do nothing, but document it.
...
... No, really, it doesn't do anything.
... """
... pass
...
>>> print(my_function.__doc__)
Do nothing, but document it.
No, really, it doesn't do anything.
6.7.函数注解
注解以字典的形式存储在函数的 __annotations__
属性中
参数注解, 定义在参数名称的冒号后面
返回注释, 定义在函数的 -> 和冒号之间
>>> def f(ham: 42, eggs: int = 'spam') -> "Nothing to see here":
... print("Annotations:", f.__annotations__)
... print("Arguments:", ham, eggs)
...
>>> f('wonderful')
Annotations: {'eggs': <class 'int'>, 'return': 'Nothing to see here', 'ham': 42}
Arguments: wonderful spam
7.一些编码风格
使用 4 空格缩进,而非 TAB.
折行以确保其不会超过 79 个字符.
使用空行分隔函数和类,以及函数中的大块代码
可能的话,注释独占一行
使用文档字符串
把空格放到操作符两边,以及逗号后面,但是括号里侧不加空格:a = f(1, 2) + g(3, 4)
统一函数和类命名, 推荐类名用 驼峰命名
, 函数和方法名用 小写和下划线
, 总是用 self
作为方法的第一个参数.
不要使用花哨的编码,如果你的代码的目的是要在国际化环境。Python 的默认情况下,UTF-8,甚至普通的 ASCII 总是工作的最好.
同样,也不要使用非 ASCII 字符的标识符,除非是不同语种的会阅读或者维护代码。