Python:这里有什么类型的对象?

时间:2016-03-09 18:47:17

标签: python for-loop

我正在努力学习LPTHW http://learnpythonthehardway.org/book/ex39.html

这本书

以下是代码:

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

kvget_slot的含义是什么?这是什么类型的对象?为什么下面的代码不起作用?我得到TypeError: 'int' object is not iterable

for i, kv in enumerate([1,2,3,4,5]):
    k, v = kv
    print(kv)

更新: 再次检查enumerate的工作原理是个好主意 https://docs.python.org/2/library/functions.html#enumerate。感谢大家的答案。

2 个答案:

答案 0 :(得分:4)

kv被赋予get_bucket(aMap, key)生成的序列中的一个值;每次迭代enumerate()都会产生另一个值(与整数计数器一起,在示例代码中分配给i)。显然,这些对象中的每一个本身都是一个带有两个元素的迭代。

您的尝试产生了一个只有整数的列表,这些列表本身不可迭代,这就是k, v = kv赋值失败的原因。试试这个:

for i, kv in enumerate([('foo', 1), ('bar', 2), ('baz', 3)]):
    k, v = kv

这会迭代一系列(str, int)元组,因此k, v = kv可迭代解包工作。

通常,所有enumerate()都会添加一个序列号;默认值是从0开始。因此,对于for循环中的每次迭代,enumerate(something)生成(counter, value_from_something)value_from_something本身仍然只是一个Python对象,它可以支持各种操作。

您可以从同一示例中的new()函数中看到代码处理列表列表:

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

所以aMap是包含其他列表的列表。代码将每个列表称为 buckets set()函数显示这些存储桶包含带有两个值的元组,键和值:

else:
    # the key does not, append to create it
    bucket.append((key, value))

get_slot()函数处理其中一个桶,其中包含0个或更多(key, value)个对(并且所有键都已散列到同一个桶中)。

答案 1 :(得分:1)

enumerate()会返回iterator个元组。每个元组都是一个索引和一个值。例如,如果您说enumerate([2, 3, 4]),则会获得(0, 2)(1, 3)(2, 4)。由于您使用的是for i, kv in enumerate(...),因此第一次迭代会有i == 0kv == 2。然后你说k, v = kv,但kv只是一个整数。它不是元组或列表等,因此您无法将其拆分为两个变量。如果您改为说enumerate([(2, 3), (4, 5), (6, 7]),那么您可以这样做,因为当i0kv(2, 3)kv可以分为两个变量,k2v3