函数,缩进和计数

在Sage中定义一个新的函数,需要使用def命令,并且在变量列表后跟一个冒号。比如:

  1. sage: def is_even(n):
  2. ....: return n%2 == 0
  3. sage: is_even(2)
  4. True
  5. sage: is_even(3)
  6. False

注:根据你所阅读的本教程的版本的不同,在这个例子中,你可能会看到第二行有四个点”....“。不要输入它们,它们只是强调一下代码是缩进的。不管是什么情况,在程序块的最后,按[Return/Enter]插入一个空行以结束函数的定义。

你没有指定输入参数的类型。你可以指定多个输入,每个参数都可以带一个可选的默认值。比如下面的函数中,如果不指定divisor的话,默认取divisor=2.

  1. sage: def is_divisible_by(number, divisor=2):
  2. ....: return number%divisor == 0
  3. sage: is_divisible_by(6,2)
  4. True
  5. sage: is_divisible_by(6)
  6. True
  7. sage: is_divisible_by(6, 5)
  8. False

在调用函数时,你还可以明确的指定一个或多个参数的值。如果你明确指定参数的值,参数可以以任何顺序出现。

  1. sage: is_divisible_by(6, divisor=5)
  2. False
  3. sage: is_divisible_by(divisor=2, number=6)
  4. True

与其他很多语言不同,Python中的程序块不用花括号或者begin,end来标记,而是用精确的缩进来标记。比如下面的代码有一个语法错误,return语句与它上面的语句缩进的不完全一致。

  1. sage: def even(n):
  2. ....: v = []
  3. ....: for i in range(3,n):
  4. ....: if i % 2 == 0:
  5. ....: v.append(i)
  6. ....: return v
  7. Syntax Error:
  8. return v

修正缩进格数之后,函数就对了:

  1. sage: def even(n):
  2. ....: v = []
  3. ....: for i in range(3,n):
  4. ....: if i % 2 == 0:
  5. ....: v.append(i)
  6. ....: return v
  7. sage: even(10)
  8. [4, 6, 8]

多数情况下,一行结束后会开始一个新行,这时行尾不需要分号。但是如果要将多个语句放在同一行,就要用分号隔开:

  1. sage: a = 5; b = a + 3; c = b^2; c
  2. 64

如果你要将一行代码分开放在多行,要在行尾使用反斜杠:

  1. sage: 2 + \
  2. ....: 3
  3. 5

在Sage中,通过遍历一个范围内的整数进行计数。比如下面代码中的第一行相当于C++或者Java中的for(i=0; i<3; i++):

  1. sage: for i in range(3):
  2. ....: print(i)
  3. 0
  4. 1
  5. 2

下面的第一行相当于for(i=2;i<5;i++).

  1. sage: for i in range(2,5):
  2. ....: print(i)
  3. 2
  4. 3
  5. 4

第三个参数控制步长,下面的第一行相当于for(i=1;i<6;i+=2).

  1. sage: for i in range(1,6,2):
  2. ....: print(i)
  3. 1
  4. 3
  5. 5

可能你经常需要将Sage中的计算结果以漂亮的表格形式输出,一个简单的方法是使用格式化字符串。下面,我们计算数的平方和立方,并建立一个有三列的表格,每一列都是6个字符宽。

  1. sage: for i in range(5):
  2. ....: print('%6s %6s %6s' % (i, i^2, i^3))
  3. 0 0 0
  4. 1 1 1
  5. 2 4 8
  6. 3 9 27
  7. 4 16 64

Sage中最最基本的数据结构是list,跟字面意思一样,list就是任意对象的列表。比如我们刚才用到的range命令就产生一个list(仅在python2中):

  1. sage: range(2,10) # py2
  2. [2, 3, 4, 5, 6, 7, 8, 9]
  3. sage: list(range(2,10)) # py3
  4. [2, 3, 4, 5, 6, 7, 8, 9]

下面是一个更复杂的list:

  1. sage: v = [1, "hello", 2/3, sin(x^3)]
  2. sage: v
  3. [1, 'hello', 2/3, sin(x^3)]

像其他很多语言一样,list的下标以0开始计数。

  1. sage: v[0]
  2. 1
  3. sage: v[3]
  4. sin(x^3)

使用len(v)得到v的长度,使用v.append(obj)v的末尾添加新的对象,使用del v[i]删除v的第i个元素:

  1. sage: len(v)
  2. 4
  3. sage: v.append(1.5)
  4. sage: v
  5. [1, 'hello', 2/3, sin(x^3), 1.50000000000000]
  6. sage: del v[1]
  7. sage: v
  8. [1, 2/3, sin(x^3), 1.50000000000000]

另一个重要的数据结构是dictionary(或associative array)。用法和list类似,但它几乎可以使用所有的对象进行索引(指标必须是固定的):

  1. sage: d = {'hi':-2, 3/8:pi, e:pi}
  2. sage: d['hi']
  3. -2
  4. sage: d[e]
  5. pi

你可以使用”类”定义新的数据结构。将数学对象用类进行封装是一个强大的技术,可以帮你简化和组织Sage程序。下面我们定义一个类来表示不超过 n的正偶数列表,它由内置类型list继承而来。

  1. sage: class Evens(list):
  2. ....: def __init__(self, n):
  3. ....: self.n = n
  4. ....: list.__init__(self, range(2, n+1, 2))
  5. ....: def __repr__(self):
  6. ....: return "Even positive numbers up to n."

在建立对象时,调用__init__方法进行初始化;__repr__方法打印对象。我们在__init__方法的第二行调用list的constructor方法。我们可以像下面一样建立Evens类的一个对象:(译注:由于e是Sage中内置的常数,因此不建议在实际中这样做来修改e)

  1. sage: e = Evens(10)
  2. sage: e
  3. Even positive numbers up to n.

注意e使用我们定义的__repr__方法进行输出。要使用list的函数才能查看隐含的数据列表:

  1. sage: list(e)
  2. [2, 4, 6, 8, 10]

我们还可以访问n属性或者将e当做list。

  1. sage: e.n
  2. 10
  3. sage: e[2]
  4. 6