教程:使用Python和Sage进行编程¶
本教程是对使用Python和Sage进行基本编程的介绍,面向对编程有基本概念但不熟悉Python语言的读者。这远远不是详尽的。有关更完整的教程,请参阅 Python Tutorial 。也是 Python 的 documentation 尤其是 standard library 可能会很有用。
A more advanced tutorial 介绍了Python中的对象和类的概念。
以下是学习Python的更多资源:
Learn Python in 10 minutes ou en français Python en 10 minutes
Dive into Python 是为有经验的程序员编写的一本Python书。还可在以下位置提供 other languages 。
Discover Python 是发表在IBM的 developerWorks 技术资源中心。
数据结构¶
在Python语言中, typing is dynamic ;没有声明变量这回事。该功能 type()
返回对象的类型 obj
。将对象转换为类型的步骤 typ
只要写信就行了 typ(obj)
如中所示 int("123")
。该命令 isinstance(ex, typ)
返回该表达式是否 ex
是一种 typ
。具体地说,任何值都是 an instance of a class 并且类和类型之间没有区别。
这个符号 =
表示对变量的影响;不应与 ==
这表示数学上的等式。不平等是 !=
。
这个 standard types 是 bool
, int
, list
, tuple
, set
, dict
, str
。
类型
bool
( booleans )有两个值:True
和False
。布尔运算符由它们的名称表示or
,and
,not
。Python类型
int
用于表示大小有限的整数。为了使用精确算术处理任意大整数,Sage使用自己的名为Integer
。A list 是对值进行分组的数据结构。它是使用方括号构建的,如
[1, 3, 4]
。这个range()
函数创建整数列表。用户还可以使用以下命令创建列表 list comprehension :[ <expr> for <name> in <iterable> (if <condition>) ]
例如::
sage: [ i^2 for i in range(10) if i % 2 == 0 ] [0, 4, 16, 36, 64]
A tuple 非常类似于列表;它是使用圆括号构建的。空元组通过以下方式获得
()
或由构造函数tuple
。如果只有一个元素,则必须写(a,)
。元组是 immutable (一个人不能改变它)但它是 hashable (见下文)。还可以使用理解来创建元组::sage: tuple(i^2 for i in range(10) if i % 2 == 0) (0, 4, 16, 36, 64)
A set 是一种数据结构,它包含没有重数或顺序的值。您可以使用构造函数从列表(或任何可迭代的)创建它
set
。集合的元素必须是可散列的::sage: set([2,2,1,4,5]) {1, 2, 4, 5} sage: set([ [1], [2] ]) Traceback (most recent call last): ... TypeError: unhashable type: 'list'
A dictionary 是一个关联表,它将值与键相关联。密钥必须是可散列的。一种是使用构造函数创建词典
dict
,或使用以下语法:{key1 : value1, key2 : value2 ...}
例如::
sage: age = {'toto' : 8, 'mom' : 27}; age {'mom': 27, 'toto': 8}
引号(简单
' '
或双倍" "
)随函附上 character strings 。可以使用以下命令将它们连接起来+
。对于列表、元组、字符串和词典, indexing operator 是这样写的
l[i]
。对于列表、元组和字符串,也可以使用 slices ASl[:]
,l[:b]
,l[a:]
,或l[a:b]
。负指数从末尾开始。这个
len()
函数返回列表、元组、集、字符串或字典的元素数。一个人写道x in C
来测试一下x
vt.在.中C
。最后,有一个特殊的值,称为
None
表示没有值。
控制结构¶
在Python中,指令块的开始和结束没有关键字。块仅通过缩进的方式来定界。大多数情况下,新块是由 :
。Python具有以下控制结构:
条件指令:
if <condition>: <instruction sequence> [elif <condition>: <instruction sequence>]* [else: <instruction sequence>]
在Exposal Exposal中,可以这样写:
<value> if <condition> else <value>
迭代说明:
for <name> in <iterable>: <instruction sequence> [else: <instruction sequence>]
while <condition>: <instruction sequence> [else: <instruction sequence>]
这个
else
如果循环正常结束,即既不是由break
也不例外。在一个循环中,
continue
跳到下一个迭代。可迭代对象是可以遍历的对象。可迭代类型包括列表、元组、字典和字符串。
错误(也称为异常)由以下各项引发:
raise <ErrorType>[("error message")]
常见错误包括
ValueError
和TypeError
。
功能¶
备注
Python函数与数学函数
在下面的内容中,我们将处理 functions 是一种 programming languages 。在微积分中操作的数学函数,由Sage以不同的方式处理。特别是,对Python函数进行加法或派生等数学操作是没有意义的。
一种使用关键字定义函数 def
作为:
def <name>(<argument list>):
<instruction sequence>
该函数的结果由指令给出 return
。可以使用以下命令匿名创建非常短的函数 lambda
(请注意,没有说明 return
在此):
lambda <arguments>: <expression>
习题¶
列表¶
创建列表I: [Square brackets]¶
Example:
sage: L = [3, Permutation([5,1,4,2,3]), 17, 17, 3, 51]
sage: L
[3, [5, 1, 4, 2, 3], 17, 17, 3, 51]
Exercise: 创建列表 [63, 12, -10, "a", 12]
,将其赋给变量 L
,并打印列表。
sage: # edit here
Exercise: 创建空列表(您经常需要这样做)。
sage: # edit here
创建列表II:范围¶
这个 range()
函数提供了一种构造整数列表的简单方法。以下是 range()
功能:
range([start,] stop[, step]) -> list of integers
Return a list containing an arithmetic progression of integers.
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement). For
example, range(4) returns [0, 1, 2, 3]. The end point is omitted!
These are exactly the valid indices for a list of 4 elements.
Exercise: 使用 range()
构建列表的步骤 [1,2,ldots,50] 。
sage: # edit here
Exercise: 使用 range()
构建……的列表 even 介于1和100(包括100)之间的数字。
sage: # edit here
Exercise: 这个 step
的论据 range()
命令可以是负的。使用Range构造列表 [10, 7, 4, 1, -2] 。
sage: # edit here
参见
xrange()
:返回迭代器,而不是构建列表,(仅适用于Python2,在Python3中替换为Range)。srange()
:Like Range,但带有Sage整数;见下文。xsrange()
:类似于xrange,但带有Sage整数。
创建列表III:列表理解¶
List comprehensions 提供从其他列表(或其他数据类型)创建列表的简明方法。
Example 我们已经知道如何创建列表 [1, 2, dots, 16] **
sage: list(range(1,17))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
使用 list comprehension ,我们现在可以创建列表了 [1^2, 2^2, 3^2, dots, 16^2] 详情如下:
sage: [i^2 for i in range(1,17)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256]
sage: sum([i^2 for i in range(1,17)])
1496
Exercise: [Project Euler, Problem 6]
前十个自然数的平方和是
前十个自然数之和的平方是
因此,前十个自然数的平方和与总和的平方之间的差为
求出前100个自然数的平方和与总和的平方之间的差值。
sage: # edit here
sage: # edit here
sage: # edit here
使用列表理解过滤列表¶
列表可以是 filtered 使用列表理解。
Example: 为了创建介于1和100之间的素数平方的列表,我们使用如下列表理解。
sage: [p^2 for p in [1,2,..,100] if is_prime(p)]
[4, 9, 25, 49, 121, 169, 289, 361, 529, 841, 961, 1369, 1681, 1849, 2209, 2809, 3481, 3721, 4489, 5041, 5329, 6241, 6889, 7921, 9409]
Exercise: 使用 list comprehension 列出20以下是3或5的倍数的所有自然数。提示:
要得到7除以3的余数,请使用
7%3
。要测试是否相等,请使用两个等号 (
==
);例如,3 == 7
。
sage: # edit here
Project Euler, Problem 1: 求1000以下3或5的所有倍数之和。
sage: # edit here
嵌套列表理解¶
列表理解可以嵌套!
Examples:
sage: [(x,y) for x in range(5) for y in range(3)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), (3, 0), (3, 1), (3, 2), (4, 0), (4, 1), (4, 2)]
sage: [[i^j for j in range(1,4)] for i in range(6)]
[[0, 0, 0], [1, 1, 1], [2, 4, 8], [3, 9, 27], [4, 16, 64], [5, 25, 125]]
sage: matrix([[i^j for j in range(1,4)] for i in range(6)])
[ 0 0 0]
[ 1 1 1]
[ 2 4 8]
[ 3 9 27]
[ 4 16 64]
[ 5 25 125]
Exercise:
A Pythagorean triple 是一个三元组 (x,y,z) 的 positive 满足条件的整数 x^2+y^2=z^2 。分量至多为的毕达哥拉斯三元组 10 包括:
\[[(3, 4, 5), (4, 3, 5), (6, 8, 10), (8, 6, 10)] \、.\]使用过滤的列表理解,构造其组成部分至多是毕达哥拉斯的三元组的列表 50 **
sage: # edit here
sage: # edit here
Project Euler, Problem 9: 恰好存在一个毕达哥拉斯的三元组 a + b + c = 1000 。找到产品 abc **
sage: # edit here
访问列表的各个元素¶
访问列表中的元素 L
,使用语法 L[i]
,在哪里 i 是项的索引。
Exercise:
构建列表
L = [1,2,3,4,3,5,6]
。是什么L[3]
?sage: # edit here
是什么
L[1]
?sage: # edit here
的第一个元素的索引是多少
L
?sage: # edit here
是什么
L[-1]
?是什么L[-2]
?sage: # edit here
是什么
L.index(2)
?是什么L.index(3)
?sage: # edit here
修改列表:更改列表中的元素¶
更改项目位置的步骤 i
一份名单上的 L
**
sage: L = ["a", 4, 1, 8]
sage: L
['a', 4, 1, 8]
sage: L[2] = 0
sage: L
['a', 4, 0, 8]
修改列表:追加和扩展¶
至 append 列表中的对象::
sage: L = ["a", 4, 1, 8]
sage: L
['a', 4, 1, 8]
sage: L.append(17)
sage: L
['a', 4, 1, 8, 17]
至 extend 由另一个列表列出的列表::
sage: L1 = [1,2,3]
sage: L2 = [7,8,9,0]
sage: L1
[1, 2, 3]
sage: L2
[7, 8, 9, 0]
sage: L1.extend(L2)
sage: L1
[1, 2, 3, 7, 8, 9, 0]
修改列表:反转、排序、...¶
sage: L = [4,2,5,1,3]
sage: L
[4, 2, 5, 1, 3]
sage: L.reverse()
sage: L
[3, 1, 5, 2, 4]
sage: L.sort()
sage: L
[1, 2, 3, 4, 5]
sage: L = [3,1,6,4]
sage: sorted(L)
[1, 3, 4, 6]
sage: L
[3, 1, 6, 4]
正在连接列表¶
要连接两个列表,请将它们与运算符相加 +
。这不是一次互换手术!
sage: L1 = [1,2,3]
sage: L2 = [7,8,9,0]
sage: L1 + L2
[1, 2, 3, 7, 8, 9, 0]
切片列表¶
您可以使用以下语法对列表进行切片 L[start : stop : step]
。这将返回一个子列表 L
。
Exercise: 下面是一些切片列表的例子。在计算单元格之前,尝试猜测输出是什么::
sage: L = list(range(20))
sage: L
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
sage: L[3:15]
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
sage: L[3:15:2]
[3, 5, 7, 9, 11, 13]
sage: L[15:3:-1]
[15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4]
sage: L[:4]
[0, 1, 2, 3]
sage: L[:]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
sage: L[::-1]
[19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Exercise (Advanced): 下面的函数将循环与上面的一些列表操作结合在一起。该函数的作用是什么?
sage: def f(number_of_iterations):
....: L = [1]
....: for n in range(2, number_of_iterations):
....: L = [sum(L[:i]) for i in range(n-1, -1, -1)]
....: return numerical_approx(2*L[0]*len(L)/sum(L), digits=50)
sage: # edit here
元组¶
A tuple 是一种 immutable 单子。也就是说,一旦创建,它就不能更改。这对于代码安全非常有用,最重要的是它创建了元组 hashable 。要创建元组,请使用圆括号而不是方括号::
sage: t = (3, 5, [3,1], (17,[2,3],17), 4)
sage: t
(3, 5, [3, 1], (17, [2, 3], 17), 4)
要创建一个Singleton元组,需要使用逗号来解决歧义:
sage: (1)
1
sage: (1,)
(1,)
我们可以从列表创建元组,反之亦然。
sage: tuple(range(5))
(0, 1, 2, 3, 4)
sage: list(t)
[3, 5, [3, 1], (17, [2, 3], 17), 4]
元组在许多方面与列表相似:
操作 |
列表的语法 |
元组的语法 |
---|---|---|
访问一封信 |
|
|
串接 |
|
|
切片 |
|
|
反转的副本 |
|
|
长度 |
|
|
尝试修改元组将失败::
sage: t = (5, 'a', 6/5)
sage: t
(5, 'a', 6/5)
sage: t[1] = 'b'
Traceback (most recent call last):
...
TypeError: 'tuple' object does not support item assignment
发电机¶
“元组理解”是不存在的。相反,该语法会生成一种称为生成器的东西。生成器允许您一次处理一个项目序列。每一项都是在需要的时候创建的,然后就被遗忘了。如果我们只需要使用每件物品一次,这将非常有效。
sage: (i^2 for i in range(5))
<generator object <genexpr> at 0x...>
sage: g = (i^2 for i in range(5))
sage: g[0]
Traceback (most recent call last):
...
TypeError: 'generator' object ...
sage: [x for x in g]
[0, 1, 4, 9, 16]
g
现在是空的。
sage: [x for x in g]
[]
一个很好的“ Python ”技巧是使用生成器作为函数的参数。我们有 not 此命令需要使用双圆括号::
sage: sum( i^2 for i in srange(100001) )
333338333350000
辞典¶
A dictionary 是另一种内置数据类型。与按从0开始的一系列数字编制索引的列表不同,词典按 keys ,可以是任何不可变的对象。字符串和数字始终可以是键(因为它们是不可变的)。在其他编程语言中,字典有时被称为“关联数组”。
有几种定义词典的方法。一种方法是使用大括号, {}
,并以逗号分隔的形式给出条目 key:value **
sage: d = {3:17, 0.5:[4,1,5,2,3], 0:"goo", 3/2 : 17}
sage: d
{0: 'goo', 0.500000000000000: [4, 1, 5, 2, 3], 3/2: 17, 3: 17}
第二种方法是使用构造函数 dict
它接受2元组的列表(或者实际上是任何可迭代的) (key, value) **
sage: dd = dict((i,i^2) for i in range(10))
sage: dd
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
对于几个重要的操作,词典充当列表和元组的角色。
操作 |
列表的语法 |
词典的语法 |
---|---|---|
访问元素 |
|
|
长度 |
|
|
正在修改 |
|
|
正在删除项目 |
|
|
sage: d[10]='a'
sage: d
{0: 'goo', 0.500000000000000: [4, 1, 5, 2, 3], 3/2: 17, 3: 17, 10: 'a'}
一个字典可以多次具有相同的值,但每个键只能出现一次,并且必须是不可变的::
sage: d = {3: 14, 4: 14}
sage: d
{3: 14, 4: 14}
sage: d = {3: 13, 3: 14}
sage: d
{3: 14}
sage: d = {[1,2,3] : 12}
Traceback (most recent call last):
...
TypeError: unhashable type: 'list'
向词典添加项的另一种方法是使用 update()
从另一个词典更新词典的方法::
sage: d = {}
sage: d
{}
sage: d.update({10 : 'newvalue', 20: 'newervalue', 3: 14, 0.5:[1,2,3]})
sage: d
{0.500000000000000: [1, 2, 3], 3: 14, 10: 'newvalue', 20: 'newervalue'}
我们可以遍历 keys ,或 values ,或者两者兼而有之。请注意,在内部,不会对键进行排序。通常,键/值的顺序将取决于不同计算机和/或同一计算机上的重复运行的存储位置可以且将会不同。但是,Sage在打印词典时会按键对词典条目进行排序,以使文档字符串更具重现性。但是,Python方法 keys()
和 values()
不会为你分拣。如果您希望您的输出是可重现的,则必须首先对其进行排序,如以下示例所示:
sage: d = {10 : 'newvalue', 20: 'newervalue', 3: 14, 0.5:(1,2,3)}
sage: sorted([key for key in d])
[0.500000000000000, 3, 10, 20]
sage: d.keys() # random order
[0.500000000000000, 10, 3, 20]
sage: sorted(d.keys())
[0.500000000000000, 3, 10, 20]
sage: d.values() # random order
[(1, 2, 3), 'newvalue', 14, 'newervalue']
sage: set(d.values()) == set([14, (1, 2, 3), 'newvalue', 'newervalue'])
True
sage: d.items() # random order
[(0.500000000000000, (1, 2, 3)), (10, 'newvalue'), (3, 14), (20, 'newervalue')]
sage: sorted([(key, value) for key, value in d.items()])
[(0.500000000000000, (1, 2, 3)), (3, 14), (10, 'newvalue'), (20, 'newervalue')]
Exercise: 考虑下面的有向图。

创建一个字典,其关键字是上述有向图的顶点,其值是它所指向的顶点的列表。例如,顶点1指向顶点2和3,因此词典将如下所示:
d = { ..., 1:[2,3], ... }
sage: # edit here
然后尝试:
sage: g = DiGraph(d)
sage: g.plot()
使用Sage类型:srange命令¶
Example: 构建一个 3 times 3 其矩阵 (i,j) 表项是有理数 frac{i}{j} 。由生成的整数 range()
是 Python 吗? int
因此,将它们相除会得到欧几里得除法(在Python2中):
sage: matrix([[i/j for j in range(1,4)] for i in range(1,4)]) # not tested
[1 0 0]
[2 1 0]
[3 1 1]
在Python3中,Python整数的除法返回一个浮点数。
而分裂Sage Integer
由一位Sage Integer
产生有理数::
sage: matrix([[ i/j for j in srange(1,4)] for i in srange(1,4)])
[ 1 1/2 1/3]
[ 2 1 2/3]
[ 3 3/2 1]
修改列表将产生后果!¶
尝试预测以下命令的结果:
sage: a = [1, 2, 3]
sage: L = [a, a, a]
sage: L
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
sage: a.append(4)
sage: L
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
现在试试这些::
sage: a = [1, 2, 3]
sage: L = [a, a, a]
sage: L
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
sage: a = [1, 2, 3, 4]
sage: L
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
sage: L[0].append(4)
sage: L
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
这就是众所周知的 reference effect 。您可以使用命令 deepcopy()
要避免这种影响::
sage: a = [1,2,3]
sage: L = [deepcopy(a), deepcopy(a)]
sage: L
[[1, 2, 3], [1, 2, 3]]
sage: a.append(4)
sage: L
[[1, 2, 3], [1, 2, 3]]
词典也会产生同样的效果::
sage: d = {1:'a', 2:'b', 3:'c'}
sage: dd = d
sage: d.update( { 4:'d' } )
sage: dd
{1: 'a', 2: 'b', 3: 'c', 4: 'd'}
循环和函数¶
有关这里发生的事情的更详细的解释,一个很好的地方是查看Python教程的以下部分:http://docs.python.org/tutorial/controlflow.html
While 环圈¶
While 循环的使用率往往不如 for Python代码中的循环::
sage: i = 0
sage: while i < 10:
....: print(i)
....: i += 1
0
1
2
3
4
5
6
7
8
9
sage: i = 0
sage: while i < 10:
....: if i % 2 == 1:
....: i += 1
....: continue
....: print(i)
....: i += 1
0
2
4
6
8
中的子句表达式的真值 while 使用以下命令计算循环 bool
**
sage: bool(True)
True
sage: bool('a')
True
sage: bool(1)
True
sage: bool(0)
False
sage: i = 4
sage: while i:
....: print(i)
....: i -= 1
4
3
2
1
For 环圈¶
这是一个基本的 for 循环遍历列表中的所有元素 l
**
sage: l = ['a', 'b', 'c']
sage: for letter in l:
....: print(letter)
a
b
c
这个 range()
当您想要生成要循环的算术级数时,函数非常有用。请注意,终结点从未包括在内:
sage: range?
sage: list(range(4))
[0, 1, 2, 3]
sage: list(range(1, 5))
[1, 2, 3, 4]
sage: list(range(1, 11, 2))
[1, 3, 5, 7, 9]
sage: list(range(10, 0, -1))
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
sage: for i in range(4):
....: print("{} {}".format(i, i*i))
0 0
1 1
2 4
3 9
您可以使用 continue 关键字立即转到循环中的下一项::
sage: for i in range(10):
....: if i % 2 == 0:
....: continue
....: print(i)
1
3
5
7
9
如果您想要跳出循环,请使用 break 关键词::
sage: for i in range(10):
....: if i % 2 == 0:
....: continue
....: if i == 7:
....: break
....: print(i)
1
3
5
如果您需要跟踪列表中的位置及其值,一种(不是很优雅的)方法是执行以下操作:
sage: l = ['a', 'b', 'c']
sage: for i in range(len(l)):
....: print("{} {}".format(i, l[i]))
0 a
1 b
2 c
它使用起来更干净 enumerate()
它提供索引和值::
sage: l = ['a', 'b', 'c']
sage: for i, letter in enumerate(l):
....: print("{} {}".format(i, letter))
0 a
1 b
2 c
您可能会得到与 enumerate()
函数通过使用 zip()
要将两个列表压缩在一起:
sage: l = ['a', 'b', 'c']
sage: for i, letter in zip(range(len(l)), l):
....: print("{} {}".format(i, letter))
0 a
1 b
2 c
For 循环使用的是Python的迭代器协议。这允许各种不同的对象被循环。例如::
sage: for i in GF(5):
....: print("{} {}".format(i, i*i))
0 0
1 1
2 4
3 4
4 1
这是怎么回事?
sage: it = iter(GF(5)); it
<generator object ...__iter__ at 0x...>
sage: next(it)
0
sage: next(it)
1
sage: next(it)
2
sage: next(it)
3
sage: next(it)
4
sage: next(it)
Traceback (most recent call last):
...
StopIteration
sage: R = GF(5)
sage: R.__iter__??
该命令 yield 提供了一种非常方便的方法来生成迭代器。我们稍后会看到更多关于它的信息。
习题¶
对于以下每个集合,计算其元素及其总和的列表。如果可能,使用两种不同的方法:使用循环和使用列表理解。
第一 n 调和级数的术语:
\[\sum_{i=1}^n\frac{1}{i}\]sage: # edit here
之间的奇数 1 和 n **
sage: # edit here
第一 n 奇数正整数::
sage: # edit here
之间的整数 1 和 n 既不能被整除,也不能被 2 也不会被 3 也不会被 5 **
sage: # edit here
第一 n 既不能被整除也不能被整除的正整数 2 也不会被 3 也不会被 5 **
sage: # edit here
功能¶
函数是使用 def 语句,并使用 return 关键词::
sage: def f(x):
....: return x*x
sage: f(2)
4
函数可以是递归的::
sage: def fib(n):
....: if n <= 1:
....: return 1
....: else:
....: return fib(n-1) + fib(n-2)
sage: [fib(i) for i in range(10)]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
函数和其他任何对象一样都是第一类对象。例如,它们可以作为参数传递给其他函数:
sage: f
<function f at 0x...>
sage: def compose(f, x, n): # computes f(f(...f(x)))
....: for i in range(n):
....: x = f(x) # this change is local to this function call!
....: return x
sage: compose(f, 2, 3)
256
sage: def add_one(x):
....: return x + 1
sage: compose(add_one, 2, 3)
5
您可以为函数中的参数指定默认值:
sage: def add_n(x, n=1):
....: return x + n
sage: add_n(4)
5
sage: add_n(4, n=100)
104
sage: add_n(4, 1000)
1004
您可以从一个函数返回多个值::
sage: def g(x):
....: return x, x*x
sage: g(2)
(2, 4)
sage: type(g)
<... 'function'>
sage: a,b = g(100)
sage: a
100
sage: b
10000
您还可以在函数中使用数量可变的参数和关键字参数:
sage: def h(*args, **kwds):
....: print("{} {}".format(type(args), args))
....: print("{} {}".format(type(kwds), kwds))
sage: h(1,2,3,n=4)
<... 'tuple'> (1, 2, 3)
<... 'dict'> {'n': 4}
让我们使用 yield 关于制作斐波纳契数生成器的说明 n **
sage: def fib_gen(n):
....: if n < 1:
....: return
....: a = b = 1
....: yield b
....: while b < n:
....: yield b
....: a, b = b, b+a
sage: for i in fib_gen(50):
....: print(i)
1
1
2
3
5
8
13
21
34
习题¶
编写一个函数
is_even
它会返回True
如果n
是均匀的,并且False
否则的话。编写一个函数
every_other
其中包含一个列表l
作为输入,并返回一个列表,其中包含l
。编写一个生成器
every_other
这需要一个可迭代的l
作为输入,并返回l
,一个接一个。编写一个函数来计算 n -第几个斐波纳契数。努力提高性能。