python基础巩固 - 数据结构和算法6-10

1.6 字典中映射多个值

  • 怎样实现一个键对应多个值得字典

一个字典就是一个键对应一个单值的映射, 如果想要一个键映射多个值, 就需要将多个值放大另外的容器里, 比如列表和集合

d = {
    'a': [1, 2, 3],
    'b': [4, 5]
}
e = {
    'a': {1, 2, 3},
    'b': {4, 5}
}

也可以使用collections模块中的defaultdict来构造这样的字段

from collections import defaultdict

d = defaultdict(list)
d['a'].append(1)
d['a'].append(2)
d['b'].append(4)

d = defaultdict(set)
d['a'].add(1)
d['a'].add(2)
d['b'].add(3)

defaultdict 会自动为将要访问的键(就算目前字典中并不存在这样的键)创建映射实体。如果你并不需要这样的特性,你可以在一个普通的字典上使用 setdefault() 方法来代替

from collections import defaultdict

d = {}
d.setdefault('a', [])
d.setdefault('a', []).append(2)
d.setdefault('b', []).append(4)
print(d)

1.7 有序字典

使用collections模块中的OrderedDict类, 在迭代操作的时候它会保持元素被插入时的顺序

from collections import OrderedDict

d = OrderedDict()
d['foo'] = 1
d['bar'] = 2
d['spam'] = 3
d['grok'] = 4
for key in d:
    # foo 1
    # bar 2
    # spam 3
    # grok 4
    print(key, d[key])

OrderedDict 内部维护着一个根据键插入顺序排序的双向链表。每次当一个新的元素插入进来的时候,它会被放到链表的尾部。对于一个已经存在的键的重复赋值不会改变键的顺序。

1.8字典的运算

  • 查找最小和最大股票价格和股票值的代码
prices = {
'ACME': 45.23,
'AAPL': 612.78,
'IBM': 205.55,
'HPQ': 37.20,
'FB': 10.75
}
min_price = min(zip(prices.values(), prices.keys()))
max_price = max(zip(prices.values(), prices.keys()))

1.9 查找两字典的相同点

  • 怎样在两个字典中寻找相同点 (比如相同的键, 相同的值)
a = {
'x' : 1,
'y' : 2,
'z' : 3
}
b = {
'w' : 10,
'x' : 11,
'y' : 2
}
# 相同的键
print(a.keys() & b.keys())  # {'x', 'y'}
# 相同键和值
print(a.items() & b.items())  # {('y', 2)}
# 查找a和b不相同的键
print(a.keys() - b.keys())  # {'z'}

1.10 删除序列相同元素并保持顺序

  • 如果序列上的值都是hashable类型, 那么可以很简单的利用集合或者生成器来解决这个问题
def dedupe(items):
    seen = set()
    for item in items:
        if item not in seen:
            yield item
            seen.add(item)

a = [1, 5, 2, 1, 9, 1, 5, 10]
list1 = dedupe(a)
print(list(list1))

1.11 命名切片

items = [0, 1, 2, 3, 4, 5, 6]
a = slice(2, 4)
print(items[a])

1.12 序列中出现次数最多的元素

使用collections.Counter类

from collections import Counter
words = [
'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the',
'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into',
'my', 'eyes', "you're", 'under'
]
word_nums = Counter(words)
top_three = word_nums.most_common(3)
print(top_three)

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

使用 operator 模块的 itemgetter 函数

from operator import itemgetter
rows = [
{'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
{'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
{'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
]
rows_by_fname = sorted(rows, key=itemgetter('fname'))
print(rows_by_fname)

itemgetter()函数也支持多个keys

rows_by_lfname = sorted(rows, key=itemgetter('lanme', 'fname'))

1.15 通过某个字段将记录分组

from operator import itemgetter
from itertools import groupby
rows = [
{'address': '5412 N CLARK', 'date': '07/01/2012'},
{'address': '5148 N CLARK', 'date': '07/04/2012'},
{'address': '5800 E 58TH', 'date': '07/02/2012'},
{'address': '2122 N CLARK', 'date': '07/03/2012'},
{'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'},
{'address': '1060 W ADDISON', 'date': '07/02/2012'},
{'address': '4801 N BROADWAY', 'date': '07/01/2012'},
{'address': '1039 W GRANVILLE', 'date': '07/04/2012'},
]
# 先根据data排序
rows.sort(key=itemgetter('date'))
for date, items in groupby(rows, key=itemgetter('date')):
    print(date)
    for i in items:
        print(' ', i)

1.16 过滤序列元素

  • 使用列表推导式
mylist = [1, 4, -5, 10, -7, 2, 3, -1]
list1 = [n for n in mylist if n > 0]
print(list1)  # [1, 4, 10, 2, 3]
  • 使用生成器的方式
mylist = [1, 4, -5, 10, -7, 2, 3, -1]
pos = (n for n in mylist if n > 0)
for x in pos:
    print(x)

1.17 从字典中提取子集

prices = {
'ACME': 45.23,
'AAPL': 612.78,
'IBM': 205.55,
'HPQ': 37.20,
'FB': 10.75
}
p1 = {key: value for key, value in prices.items() if value > 200}
print(p1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值