Python之collections容器数据类型

   在介绍collections之前,大都知道python中已经有一些数据类型,诸如list,tuple,dict这类型,而collections可以理解对上述类型的一个扩展。下面介绍一下collections中常用到的几种数据类型

1.namedtuple()

python中的tuple是可迭代的,可哈希的,但是不可修改

name_list = ("python","java","php")
for name in name_list:
    print(name)

name_dict = {}
name_dict[name_list]="result"
print(name_dict)

# 元组的拆包功能
name_list = ("小明",29,175)
name,age,height = name_list
name ,*other = name_list
print(other)

回归了tuple之后,我们介绍一下namedtuple的功能

描述一个人的特点的时候,我们会使用姓名,年龄,身高这些属性attribute去描述,自然的会创建一个类,如下

class Person():
    def __init__(self,name,age,height):
        self.name = name
        self.age = age
        self.height = height

但如果只是为了创建一个包含某些属性的数据机构的时候,使用上面的类的创建方式会非常浪费空间内存,而且代码较为繁琐,此时就可以使用collections中的namedtuple创建一个类,因此如果是创建一些简单的对象的时候就可以使用namedtuple

from collections import namedtuple

Person = namedtuple("Person",["name","age","height"])
user = Person(name = "jack",age=29,height=175)
print(user.name,user.age,user.height)

# 函数变量参数
user_tuple = ("rose",28,165)
user2 = Person(*user_tuple)
#
user_dict ={
    "name":"rose2",
    "age":15,
    "height":160
}
user3 = Person(**user_dict)

#使用namedtuple中自带的_make函数,传入一个可迭代对象,包括list,dict,tuple
user4 = Person._make(user_tuple)

#既然是对象的属性值,肯定是可以表示成字典的形式,因此如果需要将其表示为字典
user_info_dict = user._asdict()

2.defaultdict

       常见一种统计个数的功能,str.count() 方法用于统计字符串里某个字符出现的次数,那如果是list结构中的想统计个数,可能会以如下的形式进行统计,比如统计每个成绩段的个数

grade = ["a","a","b","c"]
grade_dict = {}
for index in grade:
    if index not in grade_dict:
        grade_dict[index] = 1
    else:
        grade_dict[index] += 1

print(grade_dict)

#这个时候可以做如上优化
grade = ["a","a","b","c"]
grade_dict = {}
for index in grade:
    user_dict.setdefault(index,0)
    user_dict[index] += 1

但是一般我们可能想不到使用setdefault这个功能,这个时候就需要defaultdic这个功能了,我们知道在Python3中如果在字典中索引一个不存在的key会报错提示key-value的错误,因此使用defaultdict[key]的时候就不会报key-value的错误了

from collections import defaultdict

grade = ["a","a","b","c"]
grade_dict = defaultdict(int)
for index in grade:
    grade_dict[index] += 1
print(grade_dict)

这个最大的用处就是我们函数中经常出现判断如果传入了参数,就是用传入的参数,没有传入使用默认参数的形式,如下

def function(newDic = {}):
    # 使用sql查询一个比如某个信息info值,如果传入了info则使用传入的值,否则使用查询的值
    """"""
    temp = defaultdict(dict)
    temp.update(newDic)
    newDic = temp
    print(info if not newDic['info'] else newDic['info'])

另一种用法就是,比如在传入参数的时候,如果传入了属性,则使用传入的属性值,如果没有传入则使用默认值和上述的参数传递大同小异

def generate_dict():
    return {
        "name":"",
        "age":0
    }

default_dict = defaultdict(generate_dict)
default_dict['xiaoming']
print(default_dict)

3.deque

     queue是Python3的队列,常用以下方式进行引入

from queue import Queue

双端队列deque顾名思义就是可以在队列两边进行操作的队列,比如append,leftappend,使用之前导入对应的包

from collections import deque

具体的有哪些函数可以调用,可以导入包之后进行查看,因为可调用的函数较多,这里不再一一介绍,这里想介绍的是在队列(或者双端队列,或者列表)中,常用的一种拷贝方式,深拷贝与浅拷贝

先来看一下浅拷贝

import copy
from collections import deque

user_deque = (["boy1","boy2","boy3"])
#浅拷贝
user_deque2 = user_deque.copy()


#浅拷贝,如果对应的元素是不可变元素,如tuple中的元素,则复制该元素,如果是可变的元素,如list,就会直接指向该元素
user_deque2[1]="boy5"
print(id(user_deque),id(user_deque2))
print(user_deque,user_deque2)


#如果传入一个可变的元素
user_deque = (["boy1",["boy2","boy4"],"boy3"])
#浅拷贝
user_deque2 = user_deque.copy()
user_deque2[1].append("boy5")
print(user_deque,user_deque2)

输出结果是:

2813269021384 2813269021832
['boy1', 'boy2', 'boy3'] ['boy1', 'boy5', 'boy3']
['boy1', ['boy2', 'boy4', 'boy5'], 'boy3'] ['boy1', ['boy2', 'boy4', 'boy5'], 'boy3']

浅拷贝后,发现两个的id不一样。由于user_deque中的每个元素是字符串,即是不可变元素,所以如果是浅拷贝的话,就会是复制该元素,所以user_deque[1]的值变化了,但是user_deque没有变化。但如果是user_deque中的第二个元素变成了list,即是可变的,就会使得ID指向该新的元素

#如果传入一个可变的元素
user_deque = (["boy1",["boy2","boy4"],"boy3"])
#浅拷贝
# user_deque2 = user_deque.copy()
#深拷贝
user_deque2 = copy.deepcopy(user_deque)
user_deque2[1].append("boy5")
print(user_deque,user_deque2)

深拷贝简单的理解是两个独立的变量,一个变化不会影响另一个变量,故而有如下结论:

  • 如果源对象只有一级目录的话,源做任何改动,不影响深浅拷贝对象
  • 如果源对象不止一级目录的话,源做任何改动,都要影响浅拷贝,但不影响深拷贝

4.Counter

统计出现的次数,对比字符串中统计函数count功能

from collections import Counter

grade = ["A","A","B","C","B"]
grade_counter = Counter(grade)
print(grade_counter)

# 统计字符串中的个数
str = "uipeadsfakndfakadf"
str_counter = Counter(str)
print(str_counter)
# 合并之后进行统计
str_counter.update("sdkfnaksd")
print(str_counter)

# top n的问题,前n个出现次数最多的
print(str_counter.most_common(2))

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值