# 函数和库

## 函数的例子

#### 问题：求阶乘\begin{equation}n!\end{equation}


```python
def fac(n):                        # 求阶乘
    if n == 1:                     # 收敛条件
        return 1
    else:
        return n * fac(n - 1)      # 递归引用本函数的函数名
fac(5)
```




    120




```python
for i in range(9):                      # 需要解决fac函数的一个bug
    print(fac(i))
```

#### \begin{equation}0!=1\end{equation}


```python
fac(0)
```

#### 用循环来定义阶乘函数
```python
def fac_loop(n):
    ret = 1
    for i in range(n):
        ret = ret * (i + 1)
    return ret
```



```python
def fac_loop(n):
    ret = 1
    for i in range(n):
        ret = ret * (i + 1)
    return ret
print(fac_loop(5))
print(fac_loop(0))
print(fac_loop(1))
```

#### 问题：求组合数 \begin{equation}{n\choose k}=\frac{n!}{(n-k)!k!}\end{equation}


```python
def combination(n, k):             # 求组合数
    return fac(n) / (fac(n - k) * fac(k))
combination(52, 4)
```




    270725.0



## 函数的类型

##### 函数的类型？
```python
type(fac)
```


```python
type(fac) # 和type(True)不是一样？
```




    function



>函数的类型是参数类型到返回值类型两个类型集合的映射关系
#### \begin{equation} fac : int→int \end{equation}\begin{equation} combination: int, int → int \end{equation}


```python
max([23, 37, 13, 47]) # 输入类型是一个list，输出类型是一个数值
```




    47



## 方法
>第一个参数是固定函数


```python
pl = [23, 37, 13, 47]
pl.sort()              # 输入类型是一个list，输出类型是一个list，类型实例和函数名之间用一个.连接
pl
```




    [13, 23, 37, 47]




```python
help(list.sort)        # 获得在线帮助
```

    Help on method_descriptor:
    
    sort(...)
        L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*
    



```python
pl.sort(reverse=True) # 命名参数
pl
```




    [47, 37, 23, 13]




```python
help(list)             # 列出list的全部方法
```

    Help on class list in module builtins:
    
    class list(object)
     |  list() -> new empty list
     |  list(iterable) -> new list initialized from iterable's items
     |  
     |  Methods defined here:
     |  
     |  __add__(self, value, /)
     |      Return self+value.
     |  
     |  __contains__(self, key, /)
     |      Return key in self.
     |  
     |  __delitem__(self, key, /)
     |      Delete self[key].
     |  
     |  __eq__(self, value, /)
     |      Return self==value.
     |  
     |  __ge__(self, value, /)
     |      Return self>=value.
     |  
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |  
     |  __getitem__(...)
     |      x.__getitem__(y) <==> x[y]
     |  
     |  __gt__(self, value, /)
     |      Return self>value.
     |  
     |  __iadd__(self, value, /)
     |      Implement self+=value.
     |  
     |  __imul__(self, value, /)
     |      Implement self*=value.
     |  
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |  
     |  __iter__(self, /)
     |      Implement iter(self).
     |  
     |  __le__(self, value, /)
     |      Return self<=value.
     |  
     |  __len__(self, /)
     |      Return len(self).
     |  
     |  __lt__(self, value, /)
     |      Return self<value.
     |  
     |  __mul__(self, value, /)
     |      Return self*value.n
     |  
     |  __ne__(self, value, /)
     |      Return self!=value.
     |  
     |  __new__(*args, **kwargs) from builtins.type
     |      Create and return a new object.  See help(type) for accurate signature.
     |  
     |  __repr__(self, /)
     |      Return repr(self).
     |  
     |  __reversed__(...)
     |      L.__reversed__() -- return a reverse iterator over the list
     |  
     |  __rmul__(self, value, /)
     |      Return self*value.
     |  
     |  __setitem__(self, key, value, /)
     |      Set self[key] to value.
     |  
     |  __sizeof__(...)
     |      L.__sizeof__() -- size of L in memory, in bytes
     |  
     |  append(...)
     |      L.append(object) -> None -- append object to end
     |  
     |  clear(...)
     |      L.clear() -> None -- remove all items from L
     |  
     |  copy(...)
     |      L.copy() -> list -- a shallow copy of L
     |  
     |  count(...)
     |      L.count(value) -> integer -- return number of occurrences of value
     |  
     |  extend(...)
     |      L.extend(iterable) -> None -- extend list by appending elements from the iterable
     |  
     |  index(...)
     |      L.index(value, [start, [stop]]) -> integer -- return first index of value.
     |      Raises ValueError if the value is not present.
     |  
     |  insert(...)
     |      L.insert(index, object) -- insert object before index
     |  
     |  pop(...)
     |      L.pop([index]) -> item -- remove and return item at index (default last).
     |      Raises IndexError if list is empty or index is out of range.
     |  
     |  remove(...)
     |      L.remove(value) -> None -- remove first occurrence of value.
     |      Raises ValueError if the value is not present.
     |  
     |  reverse(...)
     |      L.reverse() -- reverse *IN PLACE*
     |  
     |  sort(...)
     |      L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*
     |  
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |  
     |  __hash__ = None
    


#### 问题：伟人排序
|像|姓名|出生年|寿命|
|-|-|-|-|
|        |  佛陀       | 480BC  |   80 |
|  |  孔子       | 551BC  |   73 |
|          |  柏拉图     | 428BC  |   80 |
|  | 琐罗亚斯德 | 500BC  |    ?  |







```python
# 新数据类型：dict
great = [{'name':'Buddha', 'birth':-480, 'age':80}, 
         {'name':'Confucius', 'birth':-551, 'age':73}, 
         {'name':'Plato', 'birth':-428, 'age':80}, 
         {'name':'Zoroaster', 'birth':-500, 'age':float('nan')}]
```


```python
great[0]['name'] # dict可以按照名字索引
```




    'Buddha'




```python
great[1]['age']  # dict本身可以是list的元素
```




    73



##### 无名函数
\begin{equation}\lambda\end{equation}
>先定义一个函数再使用它有时不如在用它的地方定义它


```python
great = [{'name':'Buddha', 'birth':-480, 'age':80}, 
         {'name':'Confucius', 'birth':-551, 'age':73}, 
         {'name':'Plato', 'birth':-428, 'age':80}, 
         {'name':'Zoroaster', 'birth':-500, 'age':float('nan')}]
great.sort(key=lambda person: person['age'], reverse=True) # key 参数要求一个函数类型，lambda在这里非常方便
great
```




    [{'name': 'Buddha', 'birth': -480, 'age': 80},
     {'name': 'Plato', 'birth': -428, 'age': 80},
     {'name': 'Confucius', 'birth': -551, 'age': 73},
     {'name': 'Zoroaster', 'birth': -500, 'age': nan}]




```python
great = [{'name':'Buddha', 'birth':-480, 'age':80}, 
         {'name':'Confucius', 'birth':-551, 'age':73}, 
         {'name':'Plato', 'birth':-428, 'age':80}, 
         {'name':'Zoroaster', 'birth':-500, 'age':float('nan')}]
great.sort(key=lambda o: o['birth'])
great
```




    [{'name': 'Confucius', 'birth': -551, 'age': 73},
     {'name': 'Zoroaster', 'birth': -500, 'age': nan},
     {'name': 'Buddha', 'birth': -480, 'age': 80},
     {'name': 'Plato', 'birth': -428, 'age': 80}]



## 库的安装和引用

```sh
pip3 install algorithms
```

```sh
python3 -c 'from algorithms.sort import merge_sort'
```


```python
from algorithms.sort import merge_sort
test_list = [1, 8, 3, 5, 6]
result_list = merge_sort(test_list)
result_list
```

##### 在哪里找到这些库？
[pypi](https://pypi.org/)



44f5d35d62744695b5834f75b32b78d0a03f5e57
ipynb
Jupyter Notebook
基础教程/A1-Python与基础知识/Python基础/03_函数和库.ipynb
microsoft/ai-edu
2f59fa4d3cf19f14e0b291e907d89664bcdc8df3
Apache-2.0
2019-05-07T02:48:50.000Z
2022-03-31T08:49:42.000Z
基础教程/A1-Python与基础知识/Python基础/03_函数和库.ipynb
microsoft/ai-edu
2f59fa4d3cf19f14e0b291e907d89664bcdc8df3
Apache-2.0
2019-05-13T15:07:19.000Z
2022-03-23T08:52:32.000Z
基础教程/A1-Python与基础知识/Python基础/03_函数和库.ipynb
microsoft/ai-edu
2f59fa4d3cf19f14e0b291e907d89664bcdc8df3
Apache-2.0
2019-05-07T02:55:15.000Z
2022-03-30T06:56:52.000Z
Qwen/Qwen-72B
1. YES
2. YES