首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TypeError:'enumerate‘类型的对象没有len()

TypeError:'enumerate‘类型的对象没有len()
EN

Stack Overflow用户
提问于 2020-02-11 12:38:59
回答 3查看 2.1K关注 0票数 2

下面是我的代码:

代码语言:javascript
复制
def twosum(a, t):
    a = enumerate(a)
    f, l = 0, len(a)-1
    while(f <= l):
        if (a[f][1] + a[l][1] == t):
            return [a[f][0], a[l][0]]
        else:
            f += 1
            l -= 1
    return

print(twosum([2, 7, 11, 15], 9)) 

我得到了错误:

代码语言:javascript
复制
TypeError: object of type 'enumerate' has no len()

我想我们可以把枚举对象当作列表来对待。我在网上找到了像对待列表一样对待枚举对象的解决方案。有人能解释一下为什么我会得到这个错误吗?

EN

回答 3

Stack Overflow用户

发布于 2020-02-11 14:47:57

迭代器只是将一个计数器添加到一个迭代器中,它是而不是。枚举对象可以转换为list,然后可以使用。

对于您的问题,非枚举解决方案可以是

代码语言:javascript
复制
def twosum(a, t):
    f, l = 0, len(a) - 1
    while f <= l:
        if a[f] + a[l] == t:
            return [a.index(a[f]), a.index(a[l])]
        else:
            f += 1
            l -= 1
twosum([2, 7, 11, 15], 17)

这返回0,3。对于枚举解决方案,

代码语言:javascript
复制
def twosum(a, t):
    f, l = 0, len(a)-1
    a = list(enumerate(a))
    while(f <= l):
        if (a[f][1] + a[l][1] == t):
            return [a[f][0], a[l][0]]
        else:
            f += 1
            l -= 1
twosum([2, 7, 11, 15], 17)

这也返回0,3

票数 1
EN

Stack Overflow用户

发布于 2020-02-11 15:12:00

代码语言:javascript
复制
TypeError: object of type 'enumerate' has no len()

len()函数要求对象具有或实现__len__函数。

object.__len__(self)

调用以实现内置函数len()。应返回对象的长度,一个整数>= 0。

遗憾的是,enumerate返回一个没有__len__枚举对象

代码语言:javascript
复制
>>> a = enumerate([1,2,3])
>>> a
<enumerate object at 0x10e496be0>
>>> dir(a)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__',
 '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', 
 '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__',
 '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', 
 '__sizeof__', '__str__', '__subclasshook__']

与支持len()list不同

代码语言:javascript
复制
>>> a = [1,2,3]
>>> dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', 
 ...
 '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__',  
 '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', 
 ...
 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

您还可以注意到,枚举对象也没有__getitem__方法,该方法允许您使用obj[index]访问项,就像list's一样。这就是为什么您在your answer中说“它甚至是不可订阅的”。

我想我们可以把枚举对象当作列表来对待。

不,不是真的。Python枚举对象的行为更像iterator,这是表示可能是无限的“数据流”的方式。在引发异常(StopIteration)之前,可以通过调用next()方法来访问数据。

对迭代器的__next__()方法的

重复调用(或将其传递给内置函数next())将返回流中的连续项。当没有更多的数据可用时,将引发StopIteration异常。

代码语言:javascript
复制
>>> a = enumerate([1,2,3])
>>> next(a)
(0, 1)
>>> next(a)
(1, 2)
>>> next(a)
(2, 3)
>>> next(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

我想你已经明白了,它们就像list一样,因为你也可以把它们放入一个像常规list一样的循环结构中,然后遍历每个元素:

代码语言:javascript
复制
>>> a = enumerate([1,2,3])
>>> for i in a:
...   print(i)
... 
(0, 1)
(1, 2)
(2, 3)

在这种情况下,对于每个迭代,枚举对象提供一个包含下一个元素的索引和元素本身的元组。for循环的工作方式和结束方式与您使用枚举对象的next()方法时相同。

enumerate()文档所示,如果您需要类似列表的内容,您可以简单地将其转换为list

代码语言:javascript
复制
>>> a = list(enumerate([1,2,3]))
>>> a
[(0, 1), (1, 2), (2, 3)]
票数 1
EN

Stack Overflow用户

发布于 2020-02-11 12:56:25

这个解决方案奏效了。我必须首先将枚举对象转换为列表。否则它甚至是不可订阅的。

代码语言:javascript
复制
def twosum(a, t):
    a = enumerate(a)
    a = sorted(a, key=lambda x:x[1])
    f, l = 0, len(a)-1
    while(f < l):
        if (a[f][1] + a[l][1] == t):
            return [a[f][0], a[l][0]]
        elif (a[f][1] + a[l][1] < t):
            f += 1
        else:
            l -= 1
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60162124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档