美文网首页初学者
python常用数据结构&高级函数

python常用数据结构&高级函数

作者: 锦绣拾年 | 来源:发表于2019-01-23 22:12 被阅读49次

来源 1.菜鸟教程
2.廖雪峰博客 python学习

元组 & 列表 & 字典

(来源——菜鸟教程)

序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。

list

列表是最常用的Python数据类型,它可以作为一个方括号内的逗号分隔值出现。

列表的数据项不需要具有相同的类型

创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示:

list1 = ['physics', 'chemistry', 1997, 2000] 
list2 = [1, 2, 3, 4, 5 ] 
list3 = ["a", "b", "c", "d"]

与字符串的索引一样,列表索引从0开始。列表可以进行截取、组合等。

元组

Python的元组与列表类似,不同之处在于元组的元素不能修改。

【但是:

(译: 对于不可变对象, 这里指tuple, += 并不是原子操作, 而是 extend= 两个动作, 这里 = 操作虽然会抛出异常, 但 extend操作已经修改成功了. 详细解释可以看这里)

[所以+=会修改元组]】

元组使用小括号,列表使用方括号。

元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。

如下实例:

tup1 = ('physics', 'chemistry', 1997, 2000) 
tup2 = (1, 2, 3, 4, 5 ) 
tup3 = "a", "b", "c", "d"

创建空元组

tup1 = ()

元组中只包含一个元素时,需要在元素后面添加逗号

实例(Python 3.0+)
>>>tup1 = (50)
>>> type(tup1)     # 不加逗号,类型为整型
<class 'int'>
 
>>> tup1 = (50,)
>>> type(tup1)     # 加上逗号,类型为元组
<class 'tuple'>

元组与字符串类似,下标索引从0开始,可以进行截取,组合等。

字典

字典是另一种可变容器模型,且可存储任意类型对象。

字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,格式如下所示:

d = {key1 : value1, key2 : value2 }

键一般是唯一的,如果重复最后的一个键值对会替换前面的,值不需要唯一。

>>>dict = {'a': 1, 'b': 2, 'b': '3'} 
>>> dict['b'] '3' 
>>> dict {'a': 1, 'b': '3'}

值可以取任何数据类型,但键必须是不可变的,如字符串,数字或元组。

一个简单的字典实例:

dict = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}

也可如此创建字典:

dict1 = { 'abc': 456 } dict2 = { 'abc': 123, 98.6: 37 }

访问字典里的值

把相应的键放入熟悉的方括弧,如下实例:

实例

#!/usr/bin/python   
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}   
print ("dict['Name']: ", dict['Name'] )
print ("dict['Age']: ", dict['Age'])

以上实例输出结果:

dict['Name']:  Zara
dict['Age']:  7

如果用字典里没有的键访问数据,会输出错误如下:

实例

#!/usr/bin/python   
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}   
print ("dict['Alice']: ", dict['Alice'])

以上实例输出结果:

dict['Alice']: 
Traceback (most recent call last):
  File "test.py", line 5, in <module>
    print "dict['Alice']: ", dict['Alice']
KeyError: 'Alice'

迭代器

来自https://www.liaoxuefeng.com/ 廖雪峰网站

我们已经知道,可以直接作用于for循环的数据类型有以下几种:

一类是集合数据类型,如listtupledictsetstr等;

一类是generator,包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

可以使用isinstance()判断一个对象是否是Iterable对象

凡是可作用于for循环的对象都是Iterable类型;for x in……

凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

Python的for循环本质上就是通过不断调用next()函数实现的

函数编程

https://www.liaoxuefeng.com/

1.函数可赋值给一个变量

>>> f = abs
>>> f(-10)
10

2.函数可以传参

def add(x, y, f):
    return f(x) + f(y)

当我们调用add(-5, 6, abs)时,参数xyf分别接收-56abs,根据函数定义,我们可以推导计算过程为:

x = -5
y = 6
f = abs
f(x) + f(y) ==> abs(-5) + abs(6) ==> 11
return 11

3.高级函数

map 函数

map函数:通过一个函数,可以把一种类型的list映射到另一种类型。

本质可以视为函数的运算 map(函数,Iterable)

>>> def f(x):
...     return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]

利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']

def normalize(name):
    if ord(name[0]) > 96 and ord(name[0]) < 123:
        #name[0] = chr(ord(name[0])- 32) string值不可修改
        name=chr(ord(name[0])- 32) +name[1:]
    for x in range(len(name)):
        if x > 0:
            if ord(name[x])>64 and ord(name[x]) <91:
                if x+1!=len(name):
                    #string值正确的修改方法
                    name= name[:x]+chr(ord(name[x]) + 32)+name[x+1:]
                else:
                    name = name[:x] + chr(ord(name[x]) + 32)
    return name
L1 = ['adam', 'LISA', 'barT']
L2 = list(map(normalize, L1))
print(L2)

reduce函数

reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算

#求一个序列的和
>>> from functools import reduce
>>> def add(x, y):
...     return x + y
...
>>> reduce(add, [1, 3, 5, 7, 9])
25


#字符串与数字的转换
DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}

def str2int(s):
    def fn(x, y):
        return x * 10 + y
    def char2num(s):
        return DIGITS[s]
    return reduce(fn, map(char2num, s))
#map函数返回单个数字,reduce函数累加实现转换
#字符转浮点数
CHAR_TO_FLOAT = {
    '0': 0,
    '1': 1,
    '2': 2,
    '3': 3,
    '4': 4,
    '5': 5,
    '6': 6,
    '7': 7,
    '8': 8,
    '9': 9,
    '.': -1
}

def str2float(s):
    nums = map(lambda ch: CHAR_TO_FLOAT[ch], s)#得到单个字符
    point = 0
    def to_float(f, n):#函数内函数
        nonlocal point#非局部变量
        if n == -1:#如果下一个为-1
            point = 1
            return f
        if point == 0:#小数点前
            return f * 10 + n
        else:#小数点后
            point = point * 10
            return f + n / point
    return reduce(to_float, nums, 0.0)#第三个参数表函数计算初始值

filter

filter把传入的函数作用于每个元素,根据返回值是True还是False决定保留还是丢弃该元素

#删掉偶数,只保留奇数
def is_odd(n):
    return n % 2 == 1

list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 结果: [1, 5, 9, 15]

过滤去返回值是false的

排序函数

Python内置的sorted()函数就可以对list进行排序:

>>> sorted([36, 5, -12, 9, -21])
[-21, -12, 5, 9, 36]

此外,sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序:

>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]

补充:C++的sort函数

sort(re,re+m,cmp);//第三个参数表函数,
sort    对给定区间所有元素进行排序(不稳定,可能)
stable_sort 对给定区间所有元素进行稳定排序

匿名函数

当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。

在Python中,对匿名函数提供了有限支持。还是以map()函数为例,计算f(x)=x2时,除了定义一个f(x)的函数外,还可以直接传入匿名函数:

>>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
[1, 4, 9, 16, 25, 36, 49, 64, 81]

通过对比可以看出,匿名函数lambda x: x * x实际上就是:

def f(x):
    return x * x

匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。

返回函数 &装饰器

函数作为一个值被返回

略过

偏函数

【全文摘抄】

int()函数可以把字符串转换为整数,当仅传入字符串时,int()函数默认按十进制转换:

>>> int('12345')
12345

int()函数还提供额外的base参数,默认值为10。如果传入base参数,就可以做N进制的转换:

>>> int('12345', base=8)
5349
>>> int('12345', 16)
74565

假设要转换大量的二进制字符串,每次都传入int(x, base=2)非常麻烦,于是,我们想到,可以定义一个int2()的函数,默认把base=2传进去:

def int2(x, base=2):
    return int(x, base)

这样,我们转换二进制就非常方便了:

>>> int2('1000000')
64
>>> int2('1010101')
85

functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2

>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85

所以,简单总结functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

注意到上面的新的int2函数,仅仅是把base参数重新设定默认值为2,但也可以在函数调用时传入其他值:

>>> int2('1000000', base=10)
1000000

最后,创建偏函数时,实际上可以接收函数对象、*args**kw这3个参数,当传入:

int2 = functools.partial(int, base=2)

实际上固定了int()函数的关键字参数base,也就是:

int2('10010')

相当于:

kw = { 'base': 2 }
int('10010', **kw)

当传入:

max2 = functools.partial(max, 10)

实际上会把10作为*args的一部分自动加到左边,也就是:

max2(5, 6, 7)

相当于:

args = (10, 5, 6, 7)
max(*args)

结果为10

小结

当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。

相关文章

网友评论

    本文标题:python常用数据结构&高级函数

    本文链接:https://www.haomeiwen.com/subject/srqejqtx.html