社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

这个字典库引起了 Python 之父的注意!你用过吗?

Linux爱好者 • 2 年前 • 573 次点击  

【导语】:本文介绍了Bi-Dictionary 库,即“Bi-directional Dictionary”双向字典,顾名思义,该库基于Python中的字典增加了由“值”访问键的功能,开发者可以通过值来反向查找键,使得处理字典更加方便。同时,该库也引起了 Python 之父 Guido 的注意,因此,很有必须学习Bi-Dictionary 库。

简介

字典是Python中最常见的数据结构之一,在日常开发中使用的频率很高。字典由一些键值对构成,我们只能通过键访问值,但是无法通过值访问键。目前有一个第三方库很好的解决了这个问题 - Bi-Dictionary,通过使用它,我们可以由值访问键。该库甚至引起了 Python 之父 Guido 的注意,因此这一特性未来可能会被加入到Python语法中。

安装

我们可以使用pip安装bidict库:

pip install bidict

随后,需要导入该库才能使用:

from bidict import bidict

简单使用

  1. 初步使用

我们首先通过创建一个字典,该字典的键为国家的简称,值为国家的全名,再用bidict初始化这个字典:

country_abbr_bidict = bidict({'USA': 'The United States of America'})

这样,我们只需要使用inverse()方法,就可以通过国家全称获取国家简称了:

from bidict import bidict
country_abbr_bidict = bidict({'USA''The United States of America'})
shortName = country_abbr_bidict.inverse['The United States of America']
print(shortName)

结果为:USA

我们可以对比下原字典和反转后的区别:

from bidict import bidict
country_abbr_bidict = bidict({'USA''The United States of America'})
print(country_abbr_bidict)
print(country_abbr_bidict.inverse)

结果显示,inverse()方法反转了原字典的键值位置:

bidict({'USA''The United States of America'})
bidict({'The United States of America''USA'})
  1. 为何不使用Python的字典呢?

我们也可以在字典中把键值互换,再存储一份数据,这样也能实现与bidict相同的效果。我们来尝试一下:

country_abbr_dict = {
    'USA''The United States of America',
    'The United States of America''USA'
}

如果我们想把USA更新成US,可以使用update()方法,像下面这样:




    
country_abbr_dict.update({
    'US''The United States of America',
    'The United States of America''US'
})

这似乎看起来很完美,但是字典仍然保留了原来的数据:

from bidict import bidict
country_abbr_dict = {
    'USA''The United States of America',
    'The United States of America''USA'
}
country_abbr_dict.update({
    'US''The United States of America',
    'The United States of America''US'
})
print(country_abbr_dict)

在结果中我们可以看到USA也在字典中:

{'USA': 'The United States of America', 'The United States of America': 'US', 'US': 'The United States of America'}

为了避免这个问题,只能定义一个函数:

def update(d, key, val):
    oldval = d.pop(key, object())
    d.pop(oldval, None)
    oldkey = d.pop(val, object())
    d.pop(oldkey, None)
    d.update({key: val, val: key})

country_abbr_dict = {
    'USA''The United States of America',
    'The United States of America''USA'
}
update(country_abbr_dict, 'US''The United States of America')
print(country_abbr_dict)

这样就可以成功更新字典了:

{'US': 'The United States of America', 'The United States of America': 'US'}

如果使用Bidict,就非常简单了:

country_abbr_bidict.inverse['The United States of America'] = 'US'
print(country_abbr_bidict)

bidict({'US': 'The United States of America'})

Bidict用起来,明显更方便!

  1. Bidict的其他用途
  • 在查找值之前,传入默认值

Bidict继承了Python字典中的大部分特性。例如,当我们想要通过键访问bidict中的某个值时,可以传入一个默认值。这样,如果bidict中没有该值,就会将默认值作为结果返回。

from bidict import bidict
country_abbr_bidict = bidict({
    'US''The United States of America',
})
print(country_abbr_bidict.get('AU''Australia'))

结果就是我们传入的默认值:Australia

  • 加入新的键值对

Bidict加入新键值对的方式与Python的原生字典一样,我们来试试:

from bidict import bidict
country_abbr_bidict = bidict({
    'US''The United States of America',
})
country_abbr_bidict['AU'] = 'Australia'
country_abbr_bidict['CA'] = 'Canada'
print(country_abbr_bidict)

结果为:

bidict({'US': 'The United States of America', 'AU': 'Australia', 'CA': 'Canada'})

  • 检验Bidict中是否有某个特定值

(1)我们可以使用in关键字来检查Bidict中是否有CA:

'CA' in country_abbr_bidict

我们可以得到一个布尔值,表示该键是否存在于Bidict中:True

(2)同样我们也可以检查Bidict中是否有某个值,

'Australia' in country_abbr_bidict.inverse

结果显示Bidict中有该值:True

  • Pop and Delete方法

除了上述特性外,我们还可以使用Pop and Delete方法。

(1)pop()方法可以从Bidict中弹出键值对

country_abbr_bidict.pop('AU')

会返回该键对应的值:Australia

我们再看看Bidict:country_abbr_bidict

发现里面没有AU这个键值对了:bidict({'US': 'The United States of America', 'CA': 'Canada'})

(2)delete()方法可以通过键或者值的方式删除键值对

del country_abbr_bidict.inverse['Canada']
print(country_abbr_bidict)

结果显示删除成功:bidict({'US': 'The United States of America'})

  1. 约束

Python的设计理念是当程序出现错误时,一定要显示出来,Bidict的设计也遵循了这一点。Bidict的一个约束是键、值都要唯一,这是因为值也有可能会被当作键使用。因此,当我们想在Bidict中加入一个新的键值对(该键值对的值已经被其他键使用),就会报错。例如,我们想把US - The United States of America加入Bidict中,但是原字典中已有USA - The United States of America了:

from bidict import bidict
country_abbr_bidict = bidict({
    'USA''The United States of America',
})
country_abbr_bidict['US'] = 'The United States of America'

会产生如下错误:

Traceback (most recent call last):
  File "F:/Documents/其他资料/pythonprojects/01practice/app.py", line 5, in 
    country_abbr_bidict['US' ] = 'The United States of America'
  File "F:\python\lib\site-packages\bidict\_bidict.py", line 67, in __setitem__
    self.put(key, val, on_dup=self.on_dup)
  File "F:\python\lib\site-packages\bidict\_bidict.py", line 93, in put
    self._update([(key, val)], on_dup=on_dup)
  File "F:\python\lib\site-packages\bidict\_base.py", line 455, in _update
    dedup_result = self._dedup(key, val, on_dup)
  File "F:\python\lib\site-packages\bidict\_base.py", line 350, in _dedup
    raise ValueDuplicationError(val)
bidict.ValueDuplicationError: The United States of America

我们可以使用forceput()方法来避免这一错误:country_abbr_bidict.forceput('USA', 'The United States of America')

但是,如果出现了两个键的值相同这种情况,该方法会把原来的键覆盖:bidict({'US': 'The United States of America'})

  1. 其他特性
  • 更新多个键值对

putall()方法可以同时加入多个键值对到Bidict中,但传入的参数必须是可迭代的。

country_abbr_bidict.putall([
    ('AU''Australia'),
    ('CA''Canada')
])
print(country_abbr_bidict)

结果显示加入成功:bidict({'USA': 'The United States of America', 'AU': 'Australia', 'CA': 'Canada'})

当某个键值对无法传入时,那么其他键值对也无法传入:

country_abbr_bidict = bidict({'US''United States of America'})
country_abbr_bidict.putall([
    ('AU''Australia'),
    ('CA''Canada'),
    ('US''The United States of America')
])

这里出现了报错:

Traceback (most recent call last):
  File "F:/Documents/其他资料/pythonprojects/01practice/app.py", line 3, in 
    country_abbr_bidict.putall([
  File "F:\python\lib\site-packages\bidict\_bidict.py", line 179, in putall
    self._update(items, on_dup=on_dup)
  File "F:\python\lib\site-packages\bidict\_base.py", line 443, in _update
    target._update(arg, kw, rbof=False, on_dup=on_dup)
  File "F:\python\lib\site-packages\bidict\_base.py", line 455, in _update
    dedup_result = self._dedup(key, val, on_dup)
  File "F:\python\lib\site-packages\bidict\_base.py", line 343, in _dedup
    raise KeyDuplicationError(key)
bidict.KeyDuplicationError: US

而其他键值对也没有传入到Bidict中:bidict({'US': 'United States of America'})

  • forceupdate()方法的优先级

如果我们想使用该方法传入多个键值对,对Bidict进行更新,那么就要注意传入数据的先后顺序了。

如果把USA放到最后,那么最终Bidict就会使用该键:

country_abbr_bidict = bidict({'US''United States of America'})
country_abbr_bidict.forceupdate([
    ('US''The United States of America'),
    ('USA''The United States of America')
])

结果为:bidict({'USA': 'The United States of America'})

如果把US放到最后,那么字典就会将US作为键。

country_abbr_bidict.forceupdate([
    ('USA''The United States of America'),
    ('US''The United States of America')
])
print(country_abbr_bidict)

结果为:bidict({'US': 'The United States of America'})

  • 与其他数据结构交互

Bidict可以转换为其他数据结构,反之亦然。例如,我们可以把Bidict转换为字典:dict(country_abbr_bidict)

结果为:{'US': 'United States of America'}

我们再把字典转换为Bidict: bidict(dict(country_abbr_bidict))

结果为:bidict({'US': 'United States of America'})

结论

在本文中,我介绍了Bi-Dictionary库-双向字典,也称为Bidict。它不仅改进了Python字典的缺点,而且遵循了Python的设计原则。非常值得学习!

参考原文:
https://towardsdatascience.com/python-bi-dictionary-key-can-be-value-and-value-can-be-key-50715a2046af

- EOF -

推荐阅读  点击标题可跳转

1、实用!f-strings 比你想象的还要强大

2、很期待!尝鲜 Python 3.11 的 5 个新特性

3、Python 处理超大 JSON 文件,这个方法简单!


↓推荐关注↓

「Python开发精选」分享 Python 技术文章、资源、课程、资讯。


点赞和在看就是最大的支持❤️

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/144578
 
573 次点击