最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

以SortedList為例詳解Python的defaultdict對(duì)象使用自定義類型的方法

 更新時(shí)間:2022年07月27日 11:19:40   作者:zorchp  
這篇文章主要介紹了以SortedList為例詳解Python的defaultdict對(duì)象使用自定義類型的方法,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下

寫在前面

最近寫周賽題, 逃不開的一種題型是設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu), 也就是第三題, 做這種題需要的就是對(duì)語言中的容器以及常用排序查找算法的掌握, 而我只熟悉了最基本的一些方法, 做起這些題來總是超時(shí)…

為了搞定這些題, 我決定學(xué)習(xí)一下大佬們的做法, 特別是優(yōu)先隊(duì)列的方法維護(hù)有序容器以及有序列表等容器, 這些都在Python中封裝好了, 用起來很是方便, 但是采用defaultdict的時(shí)候, 其缺省數(shù)據(jù)類型常常需要與題目給出的特定結(jié)構(gòu)匹配, 這就需要定義一個(gè)新的數(shù)據(jù)類型, 下面我就以一種十分常用的結(jié)構(gòu)SortedList為例, 設(shè)置自定義的數(shù)據(jù)類型(本例為將默認(rèn)的升序列表變成降序列表).

其他的數(shù)據(jù)結(jié)構(gòu)當(dāng)然也可以根據(jù)下面列出的方法來改, 主要知識(shí)點(diǎn)就是函數(shù)與類的運(yùn)用了

第一種方法: 封裝成函數(shù)

首先導(dǎo)入需要的函數(shù), 其中neg方法可以用lambda x: -x代替, 本質(zhì)上是一樣的, 下面寫的代碼這兩種均可.

from collections import defaultdict
from sortedcontainers import (SortedList as SL, SortedKeyList as SKL)
from operator import neg  # or `lambda x: -x`

然后我們來看第一種方法, 其實(shí)封裝成函數(shù)本質(zhì)上就是將自定義對(duì)象作為函數(shù)返回值, 下面給出兩種實(shí)現(xiàn), 其實(shí)不傳入?yún)?shù)也可以, 但是這樣的話下面的第15行就不能使用了, 只能通過add()來添加值, 還是有局限的.

代碼中的d2直接用一個(gè)新的lambda函數(shù), 定義鍵, 就不需要考慮直接初始化失效的情況.

def reverseSL(x=None):
    return SL(iterable=x, key=lambda x: -x)

def reverseSL1_no_args():
    return SL(key=lambda x: -x)

d1 = defaultdict(reverseSL)
d2 = defaultdict(lambda: SL(key=neg))

data = [3, 2, 4, 1]
for i in data:
    d1[1].add(i)
    d2[1].add(i)
# 也可以直接加入排序列表
d1[2] = reverseSL([1, 2])
d2[2] = reverseSL([1, 2])
print(d1)
print(d2)

可以得到如下的結(jié)果:

defaultdict(<function reverseSL at 0x100a680d0>, {1: SortedKeyList([4, 3, 2, 1], key=<function reverseSL.<locals>.<lambda> at 0x100c659d0>), 2: SortedKeyList([2, 1], key=<function reverseSL.<locals>.<lambda> at 0x100caa550>)})
defaultdict(<function <lambda> at 0x100c65820>, {1: SortedKeyList([4, 3, 2, 1], key=<built-in function neg>), 2: SortedKeyList([2, 1], key=<function reverseSL.<locals>.<lambda> at 0x100cb9940>)})
[Finished in 214ms]

如果第15行改為:

d1[2] = reverseSL_no_args([1, 2])

就會(huì)提示:TypeError: reverseSL_no_args() takes 0 positional arguments but 1 was given, 但是add()方法不會(huì)有問題.

第二種方法: 類封裝

這種方法比較復(fù)雜, 并且有一個(gè)小坑, 這里先看第一個(gè)類的代碼.

我這里實(shí)現(xiàn)了兩個(gè)類, 其中mySL1采用的是組合的面向?qū)ο笤O(shè)計(jì)方法, mySL2用的是繼承. 第一種代碼比較多, 因?yàn)槔锩嫣砑恿艘粋€(gè)組件SortedList, 就需要重寫add().

class mySL1:
    def __init__(self, iterable=None):
        self.sl = SL(iterable=iterable, key=lambda x: -x)
    def add(self, item):
        self.sl.add(item)
    def get(self):
        return list(self.sl)
    def __repr__(self):
        return repr(self.sl)

其中的__repr__是可選的, 只是為了清楚地顯示已加入到defaultdict的數(shù)據(jù)情況. 不寫的話還得調(diào)用get()方法, 進(jìn)行字典值(values)數(shù)據(jù)的輸出, 這里為方便就直接轉(zhuǎn)換為List類型了, 如果不轉(zhuǎn)換, 沒辦法在類外通過list()進(jìn)行轉(zhuǎn)換, 因?yàn)檫@樣得到的數(shù)據(jù)不是可迭代對(duì)象, 通過直接輸出值的類型, 可以得到<class '__main__.mySL1'>.

然后是第二個(gè)類, 繼承語法簡(jiǎn)潔明了, 直接調(diào)用父類的初始化方法, 但是這里需要注意的是, 繼承SortedList類的代碼這里就不能用了, 因?yàn)槿绻€是使用SortedList, 在__init__中修改key就會(huì)提示斷言錯(cuò)誤, assert key is None, 這個(gè)問題讓我比較困惑, 甚至覺得可能繼承的方法行不通,(下面是模塊的__new__方法的源碼) 我知道了問題的所在.

    def __new__(cls, iterable=None, key=None):
        """Create new sorted list or sorted-key list instance.
        Optional `key`-function argument will return an instance of subtype
        :class:`SortedKeyList`.
        >>> sl = SortedList()
        >>> isinstance(sl, SortedList)
        True
        >>> sl = SortedList(key=lambda x: -x)
        >>> isinstance(sl, SortedList)
        True
        >>> isinstance(sl, SortedKeyList)
        True
        :param iterable: initial values (optional)
        :param key: function used to extract comparison key (optional)
        :return: sorted list or sorted-key list instance
        """
        # pylint: disable=unused-argument
        if key is None:
            return object.__new__(cls)
        else:
            if cls is SortedList:
                return object.__new__(SortedKeyList)
            else:
                raise TypeError('inherit SortedKeyList for key argument')

這里模塊的作者提供了一個(gè)SortedList的子類, 叫做SortedKeyList, 顧名思義, 就是提供了一種可以寫入key的類, 這時(shí)候繼承這個(gè)類就不會(huì)有問題了.

其實(shí)在上面的函數(shù)調(diào)用那塊, 就已經(jīng)有所提示, 輸出結(jié)果中的類型, 就顯示是SortedKeyList, 這個(gè)類型就是修改了key(使得key is not None)之后得到的對(duì)象. 大家可以嘗試一下, 如果不修改key, 就還是SortedList.

class mySL2(SKL):
    """use SortedKeyList instead SortedList,
    because SortedList cannot init argument `key`,
    `assert key is None` in its `__init__`"""

    def __init__(self, iterable=None):
        super().__init__(iterable=iterable, key=neg)

最后是創(chuàng)建defaultdict, 以及數(shù)據(jù)的讀取:

d3 = defaultdict(mySL1)
d4 = defaultdict(mySL2)
for i in [19, 11, 12, 123]:
    d3['x'].add(i)
    d4['y'].add(i)
# 或者直接通過列表初始化
d3['z'] = mySL1([1, 2])
d4['w'] = mySL2([1, 2])
print(d3)
print(d4)
print(d3['x'].get(), d3['z'].get())
print(list(d4['y']), list(d4['w']))

可以得到下面的結(jié)果:

defaultdict(<class '__main__.mySL1'>, {'x': SortedKeyList([123, 19, 12, 11], key=<function mySL1.__init__.<locals>.<lambda> at 0x1008e40d0>), 'z': SortedKeyList([2, 1], key=<function mySL1.__init__.<locals>.<lambda> at 0x100bebd30>)})
defaultdict(<class '__main__.mySL2'>, {'y': mySL2([123, 19, 12, 11], key=<built-in function neg>), 'w': mySL2([2, 1], key=<built-in function neg>)})
[123, 19, 12, 11] [2, 1]
[123, 19, 12, 11] [2, 1]

可以看出, 第一種類的創(chuàng)建, 其實(shí)最后還是用到了SortedKeyList這個(gè)子類.

到此這篇關(guān)于以SortedList為例詳解Python的defaultdict對(duì)象使用自定義類型的方法的文章就介紹到這了,更多相關(guān)Python defaultdict內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python列表的切片實(shí)例講解

    Python列表的切片實(shí)例講解

    在本篇文章里小編給大家分享了關(guān)于Python列表的切片的知識(shí)點(diǎn)實(shí)例,需要的朋友們可以參考下。
    2019-08-08
  • 簡(jiǎn)單介紹Python中利用生成器實(shí)現(xiàn)的并發(fā)編程

    簡(jiǎn)單介紹Python中利用生成器實(shí)現(xiàn)的并發(fā)編程

    這篇文章主要介紹了簡(jiǎn)單介紹Python中利用生成器實(shí)現(xiàn)的并發(fā)編程,使用yield生成器函數(shù)進(jìn)行多進(jìn)程編程是Python學(xué)習(xí)進(jìn)階當(dāng)中的重要知識(shí),需要的朋友可以參考下
    2015-05-05
  • python用tkinter開發(fā)的掃雷游戲

    python用tkinter開發(fā)的掃雷游戲

    非常簡(jiǎn)單的實(shí)現(xiàn),所以并沒有那么多繁瑣得步驟,對(duì)于這種簡(jiǎn)單得h5游戲來說,用python可以很容易就設(shè)計(jì)出來。下面就來看看實(shí)現(xiàn)步驟
    2021-06-06
  • python中關(guān)于數(shù)據(jù)類型的學(xué)習(xí)筆記

    python中關(guān)于數(shù)據(jù)類型的學(xué)習(xí)筆記

    在本篇文章里小編給大家整理了關(guān)于python中關(guān)于數(shù)據(jù)類型的學(xué)習(xí)筆記內(nèi)容,需要的朋友們可以參考下。
    2020-07-07
  • numpy.reshape(-1,1)的具體使用

    numpy.reshape(-1,1)的具體使用

    本文主要介紹了numpy.reshape(-1,1)的具體使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • python實(shí)現(xiàn)貝葉斯推斷的例子

    python實(shí)現(xiàn)貝葉斯推斷的例子

    本文介紹一個(gè)貝葉斯推斷的python實(shí)現(xiàn),并展現(xiàn)了基于標(biāo)量運(yùn)算的實(shí)現(xiàn)和基于numpy的矩陣運(yùn)算的實(shí)現(xiàn)之間的差別,感興趣的可以了解一下
    2021-09-09
  • Python多線程與異步處理在HTTP請(qǐng)求中的應(yīng)用方式

    Python多線程與異步處理在HTTP請(qǐng)求中的應(yīng)用方式

    這篇文章主要介紹了Python多線程與異步處理在HTTP請(qǐng)求中的應(yīng)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • 深入理解Python裝飾器

    深入理解Python裝飾器

    裝飾器(decorator)是一種高級(jí)Python語法。裝飾器可以對(duì)一個(gè)函數(shù)、方法或者類進(jìn)行加工。這篇文章主要介紹了深入理解Python裝飾器的相關(guān)資料,需要的朋友可以參考下
    2016-07-07
  • python導(dǎo)入時(shí)小括號(hào)大作用

    python導(dǎo)入時(shí)小括號(hào)大作用

    這篇文章主要介紹了python導(dǎo)入時(shí)小括號(hào)的大作用,非常的簡(jiǎn)單實(shí)用,希望這個(gè)小技巧能夠幫到大家
    2017-01-01
  • Python實(shí)現(xiàn)連接MySQL數(shù)據(jù)庫的常見方法總結(jié)

    Python實(shí)現(xiàn)連接MySQL數(shù)據(jù)庫的常見方法總結(jié)

    這篇文章主要為大家介紹了兩種Python中用來連接 MySQL 數(shù)據(jù)庫的方法,并且針對(duì)這兩種方法,我們還將對(duì)代碼進(jìn)行封裝和優(yōu)化,提高程序的可讀性和健壯性,需要的可以收藏一下
    2023-05-05

最新評(píng)論

眉山市| 肃北| 景洪市| 探索| 峨山| 鄂托克前旗| 桦川县| 镇江市| 沂南县| 湘乡市| 望江县| 五指山市| 华宁县| 新晃| 米脂县| 乌兰浩特市| 北海市| 犍为县| 茶陵县| 喀喇沁旗| 南宫市| 雷山县| 浑源县| 洛扎县| 安溪县| 无极县| 依安县| 钟山县| 玉门市| 抚宁县| 静宁县| 宁都县| 邯郸县| 宜阳县| 双柏县| 绥中县| 武鸣县| 舟山市| 筠连县| 灵山县| 舞钢市|