I'm struggling with the book LPTHW http://learnpythonthehardway.org/book/ex39.html
Here is the code:
def new(num_buckets=256):
"""Initializes a Map with the given number of buckets."""
aMap = []
for i in range(0, num_buckets):
aMap.append([])
return aMap
def hash_key(aMap, key):
"""Given a key this will create a number and then convert it to
an index for the aMap's buckets."""
return hash(key) % len(aMap)
def get_bucket(aMap, key):
"""Given a key, find the bucket where it would go."""
bucket_id = hash_key(aMap, key)
return aMap[bucket_id]
def get_slot(aMap, key, default=None):
bucket = get_bucket(aMap, key)
for i, kv in enumerate(bucket):
k, v = kv
if key == k:
return i, k, v
return -1, key, default
What does kv
means in get_slot
? What type of object is this? Why the code below does not work? I get TypeError: 'int' object is not iterable
for i, kv in enumerate([1,2,3,4,5]):
k, v = kv
print(kv)
Update: It was a good idea to check one more time how enumerate
works https://docs.python.org/2/library/functions.html#enumerate . Thank everyone for the answers.
kv
is assigned one of the values in the sequence that get_bucket(aMap, key)
produces; each iteration over enumerate()
produces another one of those values (together with an integer counter, assigned to i
in the example code). Apparently each one of those objects it itself an iterable with two elements.
Your attempt produced a list with just integers, which are not themselves iterable, which is why the k, v = kv
assignment fails. Try this instead:
for i, kv in enumerate([('foo', 1), ('bar', 2), ('baz', 3)]):
k, v = kv
This iterates over a sequence of (str, int)
tuples, so the k, v = kv
iterable unpacking works.
In general, all enumerate()
does is add a sequence number; the default is to start at 0. So for each iteration in a for
loop, enumerate(something)
produces (counter, value_from_something)
. That value_from_something
is itself still just a Python object, which can support all sorts of operations.
You can see from the new()
function in the same sample, that the code deals with a list of lists:
def new(num_buckets=256):
"""Initializes a Map with the given number of buckets."""
aMap = []
for i in range(0, num_buckets):
aMap.append([])
return aMap
so aMap
is a list containing other lists. The code refers to each of those lists as buckets . The set()
function shows that those buckets contain tuples with two values, the key and the value:
else:
# the key does not, append to create it
bucket.append((key, value))
The get_slot()
function handles one of those buckets, which contains 0 or more (key, value)
pairs (and all the keys have hashed to the same bucket).
enumerate()
returns an iterator of tuples. Each tuple is an index and a value. For example, if you say enumerate([2, 3, 4])
, you will get (0, 2)
, (1, 3)
, and (2, 4)
. Since you use for i, kv in enumerate(...)
, the first iteration for example will have i == 0
and kv == 2
. You then say k, v = kv
, but kv
is only one integer. It is not a tuple or a list etc. so you can't split it into two variables. If you were to say enumerate([(2, 3), (4, 5), (6, 7])
instead, you could do that because i
would be 0
when kv
is (2, 3)
. kv
could be split into two variables so that k
is 2
and v
is 3
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.