【问题标题】:What is the difference between iterable and Subscriptable? Are there any objects which fall into just one of these object types?可迭代和可下标有什么区别?是否有任何对象仅属于这些对象类型之一?
【发布时间】:2021-11-12 20:50:14
【问题描述】:

可下标和可迭代对象的区别是什么? 什么是可下标但不可迭代的对象,反之亦然?

附:可下标是其中包含其他对象的对象,而迭代器是可下标的,可以迭代。但我能想到的也不过如此。

【问题讨论】:

  • Iterables 可以用for .. in ..迭代。下标是a[b]。这两者显然不同,虽然经常相关,但它们不一定是……?!
  • 当然。仅举一个例子:set 对象是可迭代的,但不可下标。
  • "P.s. Subscriptable 是包含其他对象的对象,迭代器是可下标的,可以迭代。"不,不完全是。 Subscriptable 对象是实现__getitem__ 的对象。可迭代对象实现__iter__

标签: python python-3.x object types iterable


【解决方案1】:

可下标对象和可迭代对象有什么区别?

  • 可下标对象实现__getitem__,从而实现obj[key] 语法的评估。

  • 可迭代对象实现__iter__,因此支持迭代。

什么是可下标但不可迭代的对象

一个例子是re.match(),它返回一个不可迭代的下标。

import re
m = re.match(r"\w+ (\w+)", "Isaac Newton, physicist")

然后你可以做:

print(m[1])  # "Newton"

但这会产生异常:

for word in m:  # TypeError: 're.Match' object is not iterable
    print(word)

反之亦然?

一个例子是set,它支持迭代但不支持订阅。所以你可以这样做:

for x in set([42]):
    print(x)  # 42

...但这会产生错误:

set([42])[0]  # TypeError: 'set' object is not subscriptable

【讨论】:

    【解决方案2】:

    正如@juanpa.arrivillaga 在他的评论中所说:

    可订阅对象是实现__getitem__ 的对象。可迭代对象实现__iter__

    所以在语言层面这些概念没有直接关系

    话虽如此,最常见的容器如列表或字典都是可迭代的和可下标的。但是set 是可迭代和不可下标容器的示例,同样,生成器产生可迭代和不可下标的对象。

    我没有关于可子带但不可迭代对象的常见示例,但很容易想象一个特殊的类来验证这一点。极端情况是,如果下标可以是整数,则该对象将不是真正的可迭代对象(不能在其上使用iter),但for ... in ... 仍将通过在后台恢复为连续调用__getitem__ 来工作整数

    但这是一个可能的例子(即使我无法想象现实世界的用例):

    class SubscriptNonIter:
        def __init__(self, count):
            self._count = count
            
        def __getitem__(self, key):
            return ''.join(c for i, c in enumerate(key) if i % self._count == 0)
    

    示例用法:

    >>> x = SubscriptNonIter(2)
    >>> x['abcd']
    'ac'
    >>> for i in x:
        print(i)
    
        
    Traceback (most recent call last):
      File "...", line 1, in <module>
        for i in x:
      File "...", line 6, in __getitem__
        return ''.join(c for i, c in enumerate(key) if i % self._count == 0)
    TypeError: 'int' object is not iterable
    

    【讨论】:

      猜你喜欢
      • 2020-04-14
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-28
      • 2012-01-15
      • 2011-11-22
      相关资源
      最近更新 更多