标签:索引 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