基于 Python 3.3.4

数据类型

  • 整数
  • 浮点数,可用科学表达法,如 1.23e10
  • 字符串,使用 ''或者""包裹,使用 \转义
  • 布尔值,TrueFalse
  • 空值,None

类型转换

int('123')	#123
int('123.2')	#123
float('123.2')	#123.2
str(12.3)	#'12.3'
bool(1)		#True
bool(0)		#False
bool('')	#False
bool(None)	#False

基本运算

  • 除,分为普通除/和地板除//,前者即使是整数整除也得到浮点数,后者则向下取整
  • 取余
  • 布尔操作,andornot

字符串打印

普通打印(逗号在打印时替换为空格):

print(a, b, c, d)

格式化打印(可以用 %s%d%f%h进行占位,不知道类型的情况下可以用 %s):

print('hi, my name is %s' % name)
print('hi, we are %s %s' % (name1, name2))

list 和 tuple

list 为可变数组,tuple 为不可变数组

  • 声明
my_list = ['hi', 1, True]
my_tuple = ('hi', 1, True)
my_tuple = 'hi', 1, True
my_tuple = ('hi', )		# 只有一个元素时,一定要按照这个格式,以免产生歧义
my_tuple = ()
  • 索引

使用 负数 索引值可以从尾部索引,即 list[-1] 表示倒数第一个元素,list[-2] 表示倒数第二个元素

  • 元素操作

list 可以进行元素操作,tuple 没有这种特性

my_list = ['hi', 1, True]
my_list.append('genji')
my_list.pop(i)		# 删除特定位置元素, 默认-1

range

range 是 built-in 函数,用以快速构建特定的的整数序列:

range(stop)
range(start, stop, step)

利用 rangelisttuple 可以快速构建数组:

my_range = range(11)
my_list = list(my_range)
my_tuple = tuple(my_range)

dict 和 set

dict 相当于其他语言的 map,即储存 key-value 的结构,格式与 json 类似:

my_dict = {
            'name': 'mike',
            'age': 10,
            'hobby': ['football', 'tennis']
        }
my_dict['name']			# mike
my_dict.get('sex', 'male')		# male
'name' in my_dict	# True

dict 查找的速度比 list 更快,因其建立起了索引,但同时也牺牲了空间。

set 即无序切不重复的集合,创建需要传入一个 list 或 tuple:

my_list = ['hi', 1, True]
my_set = set(my_list)
my_set.add('genji')
my_set.remove(1)

# 交集
set1 & set2
# 并集
set1 | set2

默认参数和可变长参数

默认参数可以有效减少函数的重载:

def power(x, n=2):
  return math.pow(x, n)

power(5)	# 25
power(5, 2)	# 25

可变长参数,使用 * 来标识:

def var_args(*varargs):
    for arg in varargs:
        print(arg)

var_args(1, 2, 'hanzo')
my_tuple = 1, 2, 'hanzo'
var_args(*my_tuple)

递归和尾递归

我们写一个阶乘函数:

def factorial_1(n):
  if n == 1:
    return 1
  else:
    return n*factorial_1(n-1)

factorial_1(5)	#120

def factorial_2(x, y):
  pass

def factorial_tail(x, y):
  if x == 1:
    return y
  else:
    return factorial_tail(x - 1, x * y)
  
factorial_2(5)	#120

由于程序中是以栈的形式来调用函数的(即我们平时说的调用栈)。在普通的递归中,每递归一次就占用一个栈帧,一旦递归调用多次,调用栈就会爆掉(Stack Overflow)。而如果使用尾递归,则程序在运行时可以对其优化,使其多次递归仍只占用一个栈帧。

但是尾递归对代码结构有要求:递归 return 返回的结构只能是自身,而不能包含其他。比如我们上面的 factorial_1 函数,由于其 return 掺入了 n*,所以会建立一个新的栈帧来保存当前调用栈的数据;而 factorial_tail 函数 return 直接返回了自身,则程序可以将其优化为多次调用只占用一个栈帧。

说了这么多,Python 解释器并没有对尾递归做优化(所以我上面撤了那么多干嘛?摔),不过 Kotlin 有(滑稽。