澳门威利斯人_威利斯人娱乐「手机版」

来自 澳门威利斯人 2020-02-03 14:51 的文章
当前位置: 澳门威利斯人 > 澳门威利斯人 > 正文

字典操作进阶,数据结构和算法

化解方案

习感觉常来讲,使用 d.items() 或者 d.keys()d.values() 方法迭代出来的成分顺序是束手就禽预料的。比如对辞典 d = {'a':1, 'b':2, 'c':3} 迭代:

>>> d = dict()>>> d['a'] = 1>>> d['b'] = 2>>> d['c'] = 3>>> for k, v in d.items(): printa 1c 3b 2

每一次运营结果都可能分裂。尽管想让要素迭代的生机勃勃一和创设词典时元素的各类生机勃勃致,就要动用 collections.OrderedDict 替代普通的 dict

>>> from collections import OrderedDict>>> ordered_d = OrderedDict()>>> ordered_d['a'] = 1>>> ordered_d['b'] = 2>>> ordered_d['c'] = 3>>> for k, v in ordered_d.items(): print a 1b 2c 3

OrderedDict 实际通过维护二个双向链表来记录成分增添的次第,由此其费用的内部存款和储蓄器大概为平时词典的两倍。所以在其实使用中需综合思考各个因一直决定是不是使用 OrderedDict

Python进级篇之词典操作总括,python进阶字典

生龙活虎、与辞书值有关的计量

问题

想对字典的值举行相关测算,比如找寻辞书里对应值最大(最小)的项。

除恶务尽方案一:

意气风发旦要从词典 {'a':3, 'b':2, 'c':6} 中寻觅值最小的项,能够那样做:

>>> d = {'a':3, 'b':2, 'c':6}
>>> min(zip(d.values(), d.keys()))
(2, 'b')

值得注意的是  d.values(卡塔尔(قطر‎获取词典的满贯值,d.keys()赢得词典的全部键,何况三个类别的各种照旧维持大器晚成大器晚成对应的涉嫌。因而zip(d.values() , d.keys())真相上转移的是一个(value, key卡塔尔(قطر‎ 的队列。min 函数通过相比较类别中的元组 (value, key)找寻其最小值。

斩尽杀绝方案二:

除去接收 zip(d.values() ,  d.keys())外,还足以行使 dict.items()措施和生成器推导式来生成 (value, key卡塔尔 种类,进而传递给 min 函数举行相比:

>>> d = {'a':3, 'b':2, 'c':6}
>>> min((v ,k) for (k, v) in d.items())
(2, 'b')

这里 min 函数的参数(v ,k) for (k, v) in d.items()骨子里是三个生成器推导式(和列表推导式相仿,只是把列表推导式的 [] 改为 (卡塔尔(قطر‎ ,并且其再次回到的四个生成器而非列表),由于生成器推导式做为 min 函数的参数,所以能够省略掉两侧的括号(不做为参数时写法应该是((v ,k) for (k, v) in d.items()) )

二、词典推导式

问题

想把三个元组列表调换到五个词典,例如把[('a', 1), ('b', 2), ('c', 3)]转化为{'a': 1, 'b': 2, 'c': 3}

解决方案

看似于列表推导式,辞典推导式能够方便地从其它数据构造构造词典,比方:

>>> l = [('a', 1), ('b', 2), ('c', 3)]
>>> {k: v for k, v in l}
{'c': 3, 'b': 2, 'a': 1}

词典推导式的法规和列表推导式同样,只是把 [] 换成 {}

三、搜索字典的插花

问题

假定有八个词典:

d1 = {'a':1, 'b':2, 'c':3, 'd':4}
d2 = {'b':2, 'c':3, 'd':3, 'e':5}

要寻找那四个字典中全体公共键的项,即要获得结果 {'b':2, 'c':3}

解决方案

大家知道平日通过 d.items()主意来遍历字典,d.items() 方法重回的对象是二个类集结对象,帮衬群集的主导运算,如取交集、并集等。

>>> dict(d1.items() & d2.items()) # 取交集
{'b': 2, 'c': 3}

此外,d.keys()归来词典的键,也是三个类会集对象,要是大家只想寻找三个辞书中键形似的项,能够这么:

>>> { k:d1[k] for k in d1.keys() & d2.keys() }
{'b': 2, 'd': 4, 'c': 3}

此地如果豆蔻年华致的键对应不相同的值则去第一个词典中的值。推广开来,要是想清除掉词典中的某个键,能够如此:

>>> { k:d1[k] for k in d1.keys() - {'c', 'd'} } # - 号的含义是集合的差集操作
{'b': 2, 'a': 1}

但有点内需潜心的是,d.values()再次来到词典的值,由于字典对应的值不必然唯意气风发,所以 d.values()平日无法构成二个集结,因而也就不支持平日的联谊操作。

四、八个辞典连接成三个辞典

问题

有八个词典,比方:

d1 = {'a':1, 'b':2, 'c':3}
d2 = {'c':4, 'd':5, 'e':6}

想将这七个词典连接为一个词典,或一回性对八个字典进行迭代操作。

概念方案

使用 collections.ChainMap

>>> from collections import ChainMap

>>> chain_dict = ChainMap(d1, d2)
>>> for k, v in chain_dict.items():
    print(k, v)
a 1
e 6
d 5
c 3
b 2

ChainMap 将盛传的多少个辞典连接为多个词典,并回到三个 ChainMap 对象,这一个指标的表现就如三个单意气风发的词典,大家可以对其进行取值也许迭代等操作。注意到那边键 c 对应的值为 3,要是传入 ChainMap 的词典含有相符的键,则附和的值为先传出的辞书中的值。

此外,要是你只想单独地迭代辞书的键值对,能够组合使用 items()itertools.chain()方法:

>>> from itertools import chain
>>> for k, v in chain(d1.items(), d2.items()):
  print(k, v)

a 1
c 3
b 2
e 6
c 4
d 5

此处相似的键会被分级迭代出来。

五、保持字典有序

问题

想让词典瓜月素的迭代顺序和其参与字典的顺序保持黄金时代致

施工方案

万般来讲,使用d.items() 或者 d.keys()d.values()情势迭代出来的成分顺序是爱莫能助预料的。举例对辞典d = {'a':1, 'b':2, 'c':3}迭代:

>>> d = dict()
>>> d['a'] = 1
>>> d['b'] = 2
>>> d['c'] = 3
>>> for k, v in d.items():
  print(k, v)

a 1
c 3
b 2

每趟运转结果都或许差异。假使想让要素迭代的逐一和创建词典时成分的依次黄金年代致,将要动用 collections.OrderedDict替代它普通的 dict :

>>> from collections import OrderedDict
>>> ordered_d = OrderedDict()
>>> ordered_d['a'] = 1
>>> ordered_d['b'] = 2
>>> ordered_d['c'] = 3
>>> for k, v in ordered_d.items():
  print(k, v)

a 1
b 2
c 3

OrderedDict 实际通过维护三个双向链表来记录成分增添的依次,因而其花费的内部存款和储蓄器差不离为常常辞书的两倍。所以在骨子里运用中需综合思索各类因平素调节是不是选用OrderedDict 。

六、使字典的键映射八个值

问题

平常来说情况下词典的键只对应多少个值。将来想让三个键对应五个值。

消除方案

为了使贰个键对应多少个值,首先供给把多少个值放到三个器皿中(举个例子列表可能聚众等)。比如有这么一个列表:[('a', 1), ('a', 2), ('b', 3), ('b', 4), ('c', 5)],大家要将其转换成一个词典,保持成分的键值对应涉及,平时我们会写这么的代码:

>>> from pprint import pprint
>>> l = [('a', 1), ('a', 2), ('b', 3), ('b', 4), ('c', 5)]
>>> d = {}
>>> for k, v in l:
  if k in d:
    d[k].append(v)
  else:
    d[k] = [v]

>>> pprint(d)
{'a': [1, 2], 'b': [3, 4], 'c': [5]}

但是 if else语句让代码显得略略冗余和不错读,Python 的 defaultdict 纠正上述代码。

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for k, v in l:
  d[k].append(v)

>>> pprint(d)
defaultdict(<class 'list'>, {'c': [5], 'b': [3, 4], 'a': [1, 2]})

if else 的判语句未有了。

defaultdict 是 dict 的二个子类。对 dict 来讲,假使 key 不设有,则 dict[key] 取值操作会抛出 KeyError 万分,但是 defaultdict 则会再次来到叁个扩散 defaultdict 布局器的类的实例(举个例子三个列表)只怕自定义的缺点和失误值。因而在上例中,对于d[k].append(v),当 k 空头支票时,则会先实行 d[k] = [] 并再次回到那几个空驶列车表,进而将 v 参与到列表中。

流传 defualtdict 布局器的值不分明如果三个类,也能够是一个可调用的函数,当相应的键不在 defualtdict 中时,其暗中同意的值就为那些函数的再次来到值,举例:

>>> from collections import defaultdict
>>> def zero_default():
  return 0

>>> d = defaultdict(zero_default)
>>> d['a'] = 1
>>> d['a']
1

>>> d['b']
0

>>> d.keys()
dict_keys(['b', 'a'])
>>>

运用那样一个特色,我们得以协会Infiniti深度的词典构造:

>>> from collections import defaultdict
>>> import json
>>> tree = lambda: defaultdict(tree)
>>> d = tree()
>>> d['a']['b'] = 1
>>> print(json.dumps(d)) # 为了显示的格式更好看
{"a": {"b": 1}}

那边当实践 d['a'] 时,由于相应的键不设有,故重回贰个 defaultdict(tree),当再施行d['a']['b'] = 1时,将键 b 对应的值设为 1 。

总结

上述正是那篇文中的全体内容,希望本文的内容对我们学习恐怕选取python能有早晚的佑助,要是有疑问大家能够留言交换。

大器晚成、与词典值有关的总括 问题想对字典的值举行连锁测算,举个例子寻找字典里对应值最大(最小...

1.13通过某些关键字排序一个词典列表:

问题:有三个字典列表,想依据某些或某多少个词典字段来排序那个列表。

缓和方案:经过应用operator模块的itemgetter函数,能够特别轻便的排序那样的数据构造。

问题

想对辞书的值实行连锁测算,譬如寻找字典里对应值最大的项。

1.18映射名称到行列成分:

问题:您有一段通过下标访谈列表或许元组相月素的代码,但是这么有时候会使得你的代码难以阅读, 于是你想通过名称来做客成分。

缓慢解决方案:collections.namedtuple(State of Qatar函数通过动用二个日常的元组对象来帮您消除那些标题

寸草不留方案

为了使多少个键对应两个值,首先要求把五个值放到一个器皿中(比如列表或然聚众等)。举个例子有那般二个列表:[, , , , ] ,我们要将其转变来三个辞书,保持成分的键值对应涉及,日常大家会写这么的代码:

>>> from pprint import pprint>>> l = [, , , , ]>>> d = {}>>> for k, v in l: if k in d: d[k].append else: d[k] = [v]>>> pprint{'a': [1, 2], 'b': [3, 4], 'c': [5]}

但是 if else 语句让代码显得稍稍冗余和不利读,Pythondefaultdict 改革上述代码。

>>> from collections import defaultdict>>> d = defaultdict>>> for k, v in l: d[k].append>>> pprintdefaultdict(<class 'list'>, {'c': [5], 'b': [3, 4], 'a': [1, 2]})

if else 的判语句未有了。

defaultdictdict 的三个子类。对 dict 来说,如果 key 不存在,则 dict[key] 取值操作会抛出 KeyError 异常,但是 defaultdict 则会回到多个传开 defaultdict 构造器的类的实例只怕自定义的缺点和失误值。由此在上例中,对于 d[k].append ,当 k 空头支票时,则会先实行 d[k] = [] 并再次来到那些空驶列车表,进而将 v 加入到列表中。

传入 defualtdict 布局器的值不肯定假诺一个类,也能够是一个可调用的函数,当相应的键不在 defualtdict 中时,其私下认可的值就为那个函数的再次回到值,举例:

>>> from collections import defaultdict>>> def zero_default(): return 0>>> d = defaultdict(zero_default)>>> d['a'] = 1>>> d['a']1>>> d['b']0>>> d.keys()dict_keys(['b', 'a'])>>> 

采取那样三个表征,大家得以组织Infiniti深度的词典布局:

>>> from collections import defaultdict>>> import json>>> tree = lambda: defaultdict>>> d = tree()>>> d['a']['b'] = 1>>> print(json.dumps # 为了显示的格式更好看{"a": {"b": 1}}

那边当推行 d['a'] 时,由于相应的键不设有,故再次来到二个 defaultdict,当再进行 d['a']['b'] = 1 时,将键 b 对应的值设为 1 。

1.20统一五个词典和照耀:

问题:这段时间有多少个词典或然映射,你想将它们从逻辑上联合为一个纯粹的照射后举办某个操作, 举个例子查找值大概检查有个别键是不是留存。

化解方案:行使collections模块中的ChainMap类。二个ChainMap选择多个字典并将它们在逻辑上成为多个字典。

问题

有四个辞典,例如:

d1 = {'a':1, 'b':2, 'c':3}d2 = {'c':4, 'd':5, 'e':6}

想将那多个字典连接为三个辞典,或二遍性对四个词典举行迭代操作。

1.17从词典中提取子集:

问题:您想组织壹个词典,它是此外叁个词典的子集。

化解方案:词典推导、通过创造一个元组系列然后把它传给dict(卡塔尔国函数也能促成

问题

想把贰个元组列表调换到七个字典,举个例子把 [, , ] 转化为 {'a': 1, 'b': 2, 'c': 3}

1.15通过有些字段将记录分组:

问题:您有一个辞书或许实例的类别,然后您想依靠某个特定的字段比方date来分组迭代访问。

设计方案:itertools.groupby(State of Qatar函数对于这样的数据分组操作特别实用。

解决方案

使用 collections.ChainMap

>>> from collections import ChainMap>>> chain_dict = ChainMap>>> for k, v in chain_dict.items(): printa 1e 6d 5c 3b 2

ChainMap 将盛传的多个词典连接为二个词典,并再次来到二个 ChainMap 对象,这几个目的的作为就好像多少个纯净的词典,大家能够对其开展取值大概迭代等操作。注意到此处键 c 对应的值为 3,即便传入 ChainMap 的词典含有相像的键,则对应的值为先传出的辞典中的值。

别的,尽管你只想单独地迭代辞典的键值对,能够组合使用 items()itertools.chain() 方法:

>>> from itertools import chain>>> for k, v in chain(d1.items(), d2.items: printa 1c 3b 2e 6c 4d 5

此间相近的键会被分别迭代出来。

1.3保留最终N个因素:

问题:在迭代操作依然其余操作的时候,怎么样只保留最后有限多少个要素的历史记录?

缓慢解决方案:collections.deque

deque类能够被用在此外你只需求二个大约队列数据构造的场面

上学了 Python 基本的辞典操作后,学习那几个进级操作,让写出的代码尤其文雅精短和 pythonic 。

1.12行列中冒出次数最多的要素:

问题:哪些找出一个行列中冒出次数最多的要素呢?

杀鸡取蛋方案:collections.Counter类便是专程为那类难题而规划的, 它以至有叁个卓有功效的most_common(卡塔尔国方法直接给了答案。

本文由澳门威利斯人发布于澳门威利斯人,转载请注明出处:字典操作进阶,数据结构和算法

关键词: l 算法 操作 字典 进阶