Python中的天坑--dict

Python中的字典是无序的(不能人为重新排序):

(1)键值的哈希碰撞,hash(key1) == hash(key2)时,向字典里连续添加的这个两个键的顺序是不可以控制的,也是无法做到连续的,后来的键会按算法调整到其它位置。

(2)字典空间扩容,当键的数量超过字典默认开的空间时,字典会做空间扩容,扩容后的键顺和创建顺序就会发生变化,不受人为控制。

有序字典实现方案

1 采取对list/tuple内部元素命名的方法来代替dict

1
2
3
4
5
6
7
8
9
10
11
12
13
# Method1[推荐写法]
NAME,AGE,SEX,EMAIL = xrange(4) # py3中使用range(4)
student = ('Jan',14,'male','jan@jan.net')
#student = ['Jan',14,'male','jan@jan.net']
print(student[NAME])
# Method2
from collections import namedtuple
Student = namedtuple('Student',['name','age','sex','email'])
student= Student('Jan',14,'male','jan@jan.net')
print(student[NAME])
student.age
isinstance(student,tuple)

2 sorted()函数排序

1
2
3
4
5
6
7
8
9
my_dict={"cc":100,"aa":200,"bb":10}
# 按key升序, 返回元组列表
print(sorted(my_dict.items(),key=lambda x:x[0]))
>>>[('aa', 200), ('bb', 10), ('cc', 100)]
# 按value降序, 返回元组列表
print(sorted(my_dict.items(),key=lambda x:x[1], reverse=True))
>>>[('aa', 200), ('cc', 100), ('bb', 10)]

3 使用标准库collections中的OrderedDict()

1
2
3
4
5
6
7
8
9
10
from collections import OrderedDict
orderDict=OrderedDict()
orderDict['a']=1
orderDict['b']=2
orderDict['c']=3
print(orderDict)
>>>OrderedDict([('a', 1), ('b', 2), ('c', 3)])
# 原生dict:如果让orderDict=dict(),则会输出
# >>>{'a': 1, 'c': 3, 'b': 2}

OrderedDict()虽然是好东西,但是它内部维护了一个双向链表,若数据量很大的话,会非常消耗内存.

字典的Pythonic技巧

  • 提取部分子集
1
2
3
4
5
#提取分数超过90分的学生信息,并变成字典
students_score={'jack':80, 'james':91, 'leo':100, 'sam':60}
good_score={name:score for name,score in students_score.items() if score>90}
print(good_score)
>>>{'james': 91, 'leo': 100}
  • 字典中的最值
1
2
3
4
5
stocks={'wanke':25.6,'wuliangye':32.3,'maotai':299.5,'huatai':18.6}
print(min(stocks.values()))
>>> 18.6
print(max(stocks.values()))
>>> 299.5
  • 使用zip()进行翻转
1
2
stocks = {'wanke':25.6,'wuliangye':32.3,'maotai':299.5,'huatai':18.6}
new_stocks = zip(stocks.values(), stocks.keys())

若碰到比较大的字典,数据量很多很长的时候,最好用Python标准库里的itertools模块(这个模块非常有用,可以关注下)

1
2
3
from itertools import izip
invert_stocks2=dict(izip(stocks.itervalues(),stocks.iterkeys()))
print(invert_stocks2)

字典的方法们

  • get()

    字典的取值: 一种是使用直接key的方式来进行读取,也就是dict[key],当key不存在的时候,会发生KeyError的异常(良好的代码,一定是要考虑健壮性,切记)。另外一种则使用get的方式,当使用get方法的时候,默认情况下返回的None,如果key存在,那么就会返回这个key对应的值。

    [建议]:尽量用dict.get()来代替dict[key]

    1
    2
    3
    4
    5
    6
    print(prices.get('peach'))
    >>> None
    print(prices.get('apple'), 'Not Found')
    >>> 10
    print(prices.get('peach'), 'Not Found')
    >>> Not Found
  • pop()

    获取并删除键值对

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    d = {'name': 'kel'}
    d.pop('name')
    >>> 'kel'
    d.pop('kel')
    >>> Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    KeyError: 'kel'
    # 使用默认值,则不会在键不存在的时候出现异常
    d.pop('kel','key is not exist')
    >>> 'key is not exist'
  • setdefault()

    setdefault方法主要是用来设置字典的键值,当一个键存在的时候,直接使用已经存在的值,当键不存在的时候,那么就添加一个值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    d = {'name': 'kel'}
    d.setdefault('kel','person')
    >>> 'person'
    d
    >>> {'kel': 'person', 'name': 'kel'}
    d.setdefault('kel','animal')
    >>> 'person'
    d
    >>> {'kel': 'person', 'name': 'kel'}

    当字典中的值是列表的时候,那么就可以使用方法d.setdefault('key',[]).append(somevalue)

    1
    2
    3
    d.setdefault('abc',[]).append('123')
    d
    >>> {'kel': 'person', 'name': 'kel', 'abc': ['123']}

    当值不能重复的时候,可以使用set集合d3.setdefault('key',set()).add(somevalue)

  • fromkeys()

    创建具有默认值的字典

    1
    2
    dict.fromkeys(('age','name'), None)
    >>> {'age': None, 'name': None}

    创建字典的另外两种方式:

    1
    2
    d = dict(name='kel',age=32) # 键名不能是关键字且必须符合变量命名
    d = {'name':'kel','age':32}
  • dict1.update(dict2)

    把字典dict2的键/值对更新到dict1里

    1
    2
    3
    4
    5
    dict1 = {'Name': 'Zara', 'Age': 7}
    dict2 = {'Sex': 'female', 'Age': 666}
    dict1.update(dict2)
    dict1
    >>> {'Age': 666, 'Name': 'Zara', 'Sex': 'female'}
    1
    2
    3
    4
    5
    >>> dict1 = {'Name': 'Zara', 'Age': 7}
    >>> dict2 = {'Sex': 'female', 'Age':65536}
    >>> dict1.update(dict2)
    >>> dict1
    {'Age': 65536, 'Name': 'Zara', 'Sex': 'female'}
  • dict.has_key(key)

    如果键在字典dict里返回true,否则返回false

  • values()

    返回包含字典中所有值的列表

  • keys()

    返回包含字典中所有键的列表

-------------本文到此结束  感谢您的阅读-------------

本文标题:Python中的天坑--dict

文章作者:dscdtc

发布时间:2018-01-17

原始链接:http://dscdtc.ml/Python中的天坑-dict.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际转载请保留原文链接及作者。

©著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。