标签:索引 get 查看 **kwargs 出现 pre 而且 列表 访问
namedtuple
from collections import namedtuple
girl = namedtuple("aaa", ["name", "age", "gender", "anime"])
girl = girl(name="satori", age=18, gender="f", anime="东方地灵殿")
print(girl) # aaa(name=‘satori‘, age=18, gender=‘f‘, anime=‘东方地灵殿‘)
print(girl.name) # satori
print(girl.age) # 18
print(girl.anime) # 东方地灵殿
from collections import namedtuple
girl = namedtuple("aaa", ["name", "age", "gender", "anime"])
t = ("satori", 18, "f", "东方地灵殿")
# 也可以不指定列名,直接按照顺序传入参数
girl = girl(*t)
print(girl) # aaa(name=‘satori‘, age=18, gender=‘f‘, anime=‘东方地灵殿‘)
# 也可以传入一个字典
d = {
"name": "satori",
"age": 18,
"gender": "f",
"anime": "东方地灵殿"
}
girl = namedtuple("aaa", ["name", "age", "gender", "anime"])
girl = girl(**d)
print(girl) # aaa(name=‘satori‘, age=18, gender=‘f‘, anime=‘东方地灵殿‘)
defaultdict
# 如果是一般的字典的话,当我们想要统计次数的话
l = ["a", "b", "a", "c", "c", "a", "a"]
d = {}
for i in l:
if i not in d:
d[i] = 1
else:
d[i] += 1
print(d) # {‘a‘: 4, ‘b‘: 1, ‘c‘: 2}
# 这段代码有什么问题呢?其实没什么问题,就是当数据量大了时候,会很麻烦
# 这时候defaultdict就出现了
from collections import defaultdict
# 里面要传入一个可调用的对象,什么意思呢?
default_dict = defaultdict(int)
# 当我访问一个不存在的值
print(default_dict["a"]) # 0
default_dict = defaultdict(str)
print(default_dict["a"]) # ""
default_dict = defaultdict(tuple)
print(default_dict["a"]) # ()
default_dict = defaultdict(list)
print(default_dict["a"]) # []
default_dict = defaultdict(set)
print(default_dict["a"]) # set()
default_dict = defaultdict(dict)
print(default_dict["a"]) # {}
# 看到这应该就明白了,如果访问一个不存在的key,那么会首先创建该key,然后value对应defaultdict里面传入的类型的初始值
l = ["a", "b", "a", "c", "c", "a", "a"]
default_dict = defaultdict(int)
for i in l:
# 首先没有key会创建,然后value初始化为0,然后执行+=1
# 注意:在没有相应的key的时候,这行代码表示执行两个步骤
# 先执行default_dict[i] = 0
# 然后default_dict[i] += 1
# 当key存在的时候,直接执行+=1操作
default_dict[i] += 1
# 这样操作就大大简便了
# 普通的列表的话,也可以使用setdefault,但是还是这个简单
print(default_dict) # defaultdict(<class ‘int‘>, {‘a‘: 4, ‘b‘: 1, ‘c‘: 2})
print(type(default_dict)) # <class ‘collections.defaultdict‘>
# 也可以直接转化为字典
print(dict(default_dict)) # {‘a‘: 4, ‘b‘: 1, ‘c‘: 2}
# 那么defaultdict是如何实现的呢?主要用到了__missing__这个魔法函数
class A(dict):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def __missing__(self, key):
return key
# 必须继承dict
a = A(name="satori", age=19)
# 可以看到a中只有name和age这两个属性
print(a["name"]) # satori
print(a["age"]) # 19
# 当我访问一个不存在的属性
print(a["mmp"]) # mmp
# __missing__的作用就在于此,当然这个魔法方法只能用在dict的子类当中。要是普通的类,可以用__getattr__
# 来模拟一下defaultdict
class Satoridict(dict):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def __missing__(self, key):
self[key] = 0
return self[key]
def __getitem__(self, item):
# return self[item],不可以return self[item]
# 为什么?因为调用__getitem__,return self[item],然后又执行__getitem__,又return self[item],从而无限递归
# 那么怎么获取值呢?return item的话会不报错,但获取的只是key,得不到value啊
# 我们可以调用父类的方法
value = super().__getitem__(item)
# 会先执行__getitem__方法,在执行super().__getitem__的时候
# 如果没有__missing__方法,会报错,KeyError。
# 如果有__missing__那么会执行__missing__方法,设置self[key]=0,返回self[key]
return value
satori = Satoridict(name="Satori", age=18, gender="f")
print(satori["name"]) # Satori
print(satori["age"]) # 18
# 访问一个不存在的值
print(satori["aaa"]) # 0
deque
# 先来看看queue from queue import Queue q = Queue() q.put(1) q.put(2) q.put(3) print(q.get()) # 1 print(q.get()) # 2 print(q.get()) # 3 # 默认的队列,只能append,而且取的时候只能从头开始取
from collections import deque
# 双端队列,可以从两段插入,也可以从两段取值
q = deque(("a", "b", "c"))
q.append(1)
q.appendleft(2)
print(q) # deque([2, ‘a‘, ‘b‘, ‘c‘, 1])
# 也可以通过索引取值
print(q[1]) # a
# 通过pop取值
print(q.pop()) # 1
print(q.popleft())
print(q) # deque([‘a‘, ‘b‘, ‘c‘]), 可以看到和list一样,pop之后q的元素减少了
# deque的绝大部分api和list是一致的,只是deque多了appendleft,popleft,extendleft
# 对list如何操作,对deque也如何操作就行了,会list就会deque,这里的一些方法不赘述了
# 最重要的一点,deque和queue一样也是线程安全的,是由GIL这把超级大锁保护的
# 和queue相比,deque还有一个重要的地方
import queue
q1 = queue.Queue(maxsize=3)
q2 = deque(maxlen=3)
# 当q1塞满三个元素之后,再想塞第四个就塞不进去为了
# 但是对q2来说,塞多少个都没问题,我们来打印一下
q2.append(1)
q2.append(2)
q2.append(3)
print(q2) # deque([1, 2, 3], maxlen=3)
q2.append(4)
print(q2) # deque([2, 3, 4], maxlen=3)
q2.append(5)
print(q2) # deque([3, 4, 5], maxlen=3)
q2.append(6)
print(q2) # deque([4, 5, 6], maxlen=3)
# 可以看到最多容纳三个,再添加的话那么,会被挤掉。可以用来制作历史记录,最多查看多少次等等
try:
q2.insert(1, "satori")
except Exception as e:
print(e) # deque already at its maximum size
# 另外在满了的时候,不可以通过insert插入值
# 那么appendleft可以吗?我们来试试
q2.appendleft("satori")
print(q2) # deque([‘satori‘, 4, 5], maxlen=3)
# 6没有了
# 可以看到,当从后面插入的时候(o(*////▽////*)q),那么前面的会被挤掉
# 从前面插入的时候(o(*////▽////*)q),后面会被挤掉
# extend呢?
q2.extend(["mashiro", "miku"])
print(q2) # deque([5, ‘mashiro‘, ‘miku‘], maxlen=3)
# 可以看到,satori和4没有了,说明extend也是可以的
# 同理extendleft也可以使用,这里不再试了
Counter
from collections import Counter
# 在defaultdict的时候,我们统计了列表里面的值的个数
# Counter可以做的更方便
l = ["a", "b", "a", "c", "c", "a", "a"]
c = Counter(l)
print(c) # Counter({‘a‘: 4, ‘c‘: 2, ‘b‘: 1})
# 结果直接统计出来了
# 而且Counter对象是dict的一个子类,说明字典的api,Counter也可以使用
print(c["a"]) # 4
# 当然也可以转化为字典
print(dict(c)) # {‘a‘: 4, ‘b‘: 1, ‘c‘: 2}
# 不仅是list,只要是可迭代对象都是可以的
s = "aaaabbbccd"
c2 = Counter(s)
print(c2) # Counter({‘a‘: 4, ‘b‘: 3, ‘c‘: 2, ‘d‘: 1})
# 上面也说了,Counter是dict的一个子类
# 那么Counter也可以使用update方法,而且更强大
c2.update("abcd")
print(c2) # Counter({‘a‘: 5, ‘b‘: 4, ‘c‘: 3, ‘d‘: 2})
# 可以看到将abcd和上面的s进行一个合并的统计
# 你以为强大就强大在这里吗?
c2.update(["a", "b", "c", "d", "古明地盆"])
print(c2) # Counter({‘a‘: 6, ‘b‘: 5, ‘c‘: 4, ‘d‘: 3, ‘古明地盆‘: 1})
# 我还可以update一个列表,那么列表里面的元素会作为(古明地盆)一个整体统计
# 此外update还可以接受一个Counter
c3 = Counter("aaaaaaaaaaa")
print(c3) # Counter({‘a‘: 11})
c2.update(c3)
print(c2) # Counter({‘a‘: 17, ‘b‘: 5, ‘c‘: 4, ‘d‘: 3, ‘古明地盆‘: 1})
# 还有一个最重要的方法
# 如果我们想要在c2中选出value最大的三个key该怎么办呢?
# 直接实现会很麻烦,可以使用heapq,当然Counter底层也是调用了heapq
import heapq
print(heapq.nlargest(3, c2, key=lambda x: c2[x])) # [‘a‘, ‘b‘, ‘c‘]
# 再来看看Counter
print(c2.most_common(3)) # [(‘a‘, 17), (‘b‘, 5), (‘c‘, 4)]
# 会将key,和key对应的最大的value按照顺序以列表嵌套元组的方式显示出来,非常的直观
# 你以为Counter就到此为止了,确实目前来说已经够用了
# 但是还有一些黑科技
print(c2) # Counter({‘a‘: 17, ‘b‘: 5, ‘c‘: 4, ‘d‘: 3, ‘古明地盆‘: 1})
print(c3) # Counter({‘a‘: 11})
print(c2 + c3) # Counter({‘a‘: 28, ‘b‘: 5, ‘c‘: 4, ‘d‘: 3, ‘古明地盆‘: 1})
# c2 + c3,表示将两者的结果进行组合,key相同,那么将对应的value相加
print(c2 - c3) #Counter({‘a‘: 6, ‘b‘: 5, ‘c‘: 4, ‘d‘: 3, ‘古明地盆‘: 1})
# c2 - c3,表示如果c3中有c2的元素,就把该元素从c2当中减去,当然还有数量的问题
# 既然如此,那么Counter是否支持集合的操作呢?比如&|^等等
# 我们来看看
c4 = Counter("aabbbcc")
c5 = Counter("bbccdd")
print(c4) # Counter({‘b‘: 3, ‘a‘: 2, ‘c‘: 2})
print(c5) # Counter({‘b‘: 2, ‘c‘: 2, ‘d‘: 2})
# c4 & c5,和c4 + c5不同,这真的是在做交集,不会相加
# 并且key相同的话,选择value小的那一个
print(c4 & c5) # Counter({‘b‘: 2, ‘c‘: 2})
# key相同,也不会将value相加,而是选择value较大的那一个
print(c4 | c5) # Counter({‘b‘: 3, ‘a‘: 2, ‘c‘: 2, ‘d‘: 2})
‘‘‘
print(c4 ^ c5),Counter不支持^(也就是对称差集)的操作,也没什么意义
‘‘‘
# 以上就是我能想到的Counter的全部内容了,也许还有一些方法没有介绍到
# 但是你会字典的那些方法的话,也肯定会Counter的那些方法
# Counter最主要的概念和用法就说到这里,个人认为应该就是够用了
OrderedDict
from collections import OrderedDict
# 从字面理解就知道是一个排好序的dict
# 继承自dict,所以dict有的api,它都有
d = OrderedDict()
d["a"] = 1
d["e"] = 2
d["c"] = 3
print(d) # OrderedDict([(‘a‘, 1), (‘e‘, 2), (‘c‘, 3)])
# 显然和我们添加顺序是一样的
# 除此之外再介绍一个api,move_to_end
d.move_to_end("a") # 从名字也可以理解出,把a移到最后
print(d) # OrderedDict([(‘e‘, 2), (‘c‘, 3), (‘a‘, 1)])
# 其他的和字典类似,就不介绍了。
ChainMap
from collections import ChainMap
d1 = {"a": 1, "b": 2}
d2 = {"c": 2, "d": 2}
d = ChainMap(d1, d2)
for k, v in d.items():
print(k, v)
‘‘‘
c 2
d 2
a 1
b 2
‘‘‘
# 因此ChainMap的作用就是将多个字典组合成一个字典
# 如果多个字典,key重合了会怎么样?
d3 = {"a": 1, "b": 2}
d4 = {"b":3, "c": 4}
d = ChainMap(d3, d4)
for k, v in d.items():
print(k, v)
‘‘‘
a 1
b 2
c 4
‘‘‘
# 可以看到即使value不一样,还是只打印了第一个
# 这个方法比较像chain
from itertools import chain
a = [1, 2, 3]
b = "abc"
c = {1, 2, 3}
d = {"name": "satori", "age": 15}
for i in chain(a, b, c, d):
print(i)
‘‘‘
1
2
3
a
b
c
1
2
3
name
age
‘‘‘
标签:索引 get 查看 **kwargs 出现 pre 而且 列表 访问
原文地址:https://www.cnblogs.com/traditional/p/9383979.html