## 龙哥盟飞龙 / lmpythw-zh

ex17.md 14.83 KB wizardforcel 提交于 2017-08-08 10:54 . ex18.

# 练习 17：字典

```cars = {'Toyota': 4, 'BMW': 20, 'Audi': 10}
```

## 制作一份“代码大师的副本”

• 复制代码，使其正常工作。你的副本应该完全一样。这有助于你了解它，并强制你仔细研究它。
• 使用注释来标注代码，并为所有代码写一个分析，确保你了解每一行以及它的作用。这可能涉及到你编写的其他代码，来将整个概念结合在一起。
• 使用简洁的说明，为这个代码的工作原理总结一般结构。这是函数列表和每个函数的作用。
• 记住这个算法和关键代码段的简洁描述。
• 根据记忆实现可以实现的东西，当你用尽细节时，回顾你的笔记和原始代码来记住更多内容。
• 当你需要从你的记忆中复制的时候，重复此过程多次。你的记忆中的副本并不必须是完全一样的，但应接近，并通过你创建的相同测试。

## 复制代码

```from dllist import DoubleLinkedList

class Dictionary(object):
def __init__(self, num_buckets=256):
"""Initializes a Map with the given number of buckets."""
for i in range(0, num_buckets):

def hash_key(self, key):
"""Given a key this will create a number and then convert it to
an index for the aMap's buckets."""
return hash(key) % self.map.count()

def get_bucket(self, key):
"""Given a key, find the bucket where it would go."""
bucket_id = self.hash_key(key)
return self.map.get(bucket_id)

def get_slot(self, key, default=None):
"""
Returns either the bucket and node for a slot, or None, None
"""
bucket = self.get_bucket(key)

if bucket:
node = bucket.begin
i = 0

while node:
if key == node.value[0]:
return bucket, node
else:
node = node.next
i += 1

# fall through for both if and while above
return bucket, None

def get(self, key, default=None):
"""Gets the value in a bucket for the given key, or the default."""
bucket, node = self.get_slot(key, default=default)
return node and node.value[1] or node

def set(self, key, value):
"""Sets the key to the value, replacing any existing value."""
bucket, slot = self.get_slot(key)

if slot:
# the key exists, replace it
slot.value = (key, value)
else:
# the key does not, append to create it
bucket.push((key, value))

def delete(self, key):
"""Deletes the given key from the Map."""
bucket = self.get_bucket(key)
node = bucket.begin

while node:
k, v = node.value
if key == k:
bucket.detach_node(node)
break

def list(self):
"""Prints out what's in the Map."""
bucket_node = self.map.begin
while bucket_node:
slot_node = bucket_node.value.begin
while slot_node:
print(slot_node.value)
slot_node = slot_node.next
bucket_node = bucket_node.next
```

```from dictionary import Dictionary

# create a mapping of state to abbreviation
states = Dictionary()
states.set('Oregon', 'OR')
states.set('Florida', 'FL')
states.set('California', 'CA')
states.set('New York', 'NY')
states.set('Michigan', 'MI')

# create a basic set of states and some cities in them
cities = Dictionary()
cities.set('CA', 'San Francisco')
cities.set('MI', 'Detroit')
cities.set('FL', 'Jacksonville')

cities.set('NY', 'New York')
cities.set('OR', 'Portland')

# print(out some cities
print('-' * 10)
print("NY State has: %s" % cities.get('NY'))
print("OR State has: %s" % cities.get('OR'))

# print(some states
print('-' * 10)
print("Michigan's abbreviation is: %s" % states.get('Michigan'))
print("Florida's abbreviation is: %s" % states.get('Florida'))

# do it by using the state then cities dict
print('-' * 10)
print("Michigan has: %s" % cities.get(states.get('Michigan')))
print("Florida has: %s" % cities.get(states.get('Florida')))

# print(every state abbreviation
print('-' * 10)
states.list()

# print(every city in state
print('-' * 10)
cities.list()

print('-' * 10)
state = states.get('Texas')

if not state:
print("Sorry, no Texas.")

# default values using ||= with the nil result
# can you do this on one line?
city = cities.get('TX', 'Does Not Exist')
print("The city for the state 'TX' is: %s" % city)
```

## 记忆摘要

• 确保你有一个纸质的笔记本，以及摘要和代码的打印。
• 花3分钟，只需阅读摘要并尝试记住它。静静地看着它，大声读出来，然后闭上眼睛，重复你所读的内容，甚至尝试记住纸上的单词的“形状”。听起来很愚蠢，但相信我，它完全奏效。记住你的大脑比你想象的更好。
• 把摘要翻过来，并尝试从你记住的内容中再次写出来，当你卡住时，将其快速翻过来并查看。在你快速瞥见之后，把摘要翻过来，并尝试完成更多。
• 一旦从（大部分）记忆中写出了摘要的副本，请使用摘要，花另一个 3 分钟，试图记住带标注的代码。仅仅阅读摘要的一部分，然后再看看代码的相关部分，并尝试记住它。甚至每个函数只能花 3 分钟。
• 一旦你花时间试图记住带标注的代码，把它翻过去，使用摘要，尝试回忆你笔记本中的代码。同样，当你陷入困境时，快速把标注翻过来并查看。
• 继续这样做，直到你可以在纸上写出代码的完整副本。你纸上的代码不一定是完美的 Python 代码，但应该非常接近原始代码。

## 深入学习

• 我的测试非常有限。写一个更广泛的测试。
• 练习 16 的排序算法如何有助于这个数据结构？
• 当你将键和值随机化，用于这个数据结构时，会发生什么？排序算法有帮助吗？
• `num_buckets`对数据结构有什么影响？