简体   繁体   中英

Python: what type of object is here?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM