可迭代和可订阅有什么区别?是否有任何对象仅属于这些对象类型中的一种?
What is the difference between iterable and Subscriptable? Are there any objects which fall into just one of these object types?
可订阅和可迭代 对象之间的区别是什么?
什么是可订阅但不可迭代的对象,反之亦然?
P.s。可订阅的是其中包含其他对象的对象,迭代器是可订阅的,可以迭代。但我能想到的也仅此而已。
正如@juanpa.arrivillaga 在他的评论中所说:
Subscriptable objects are objects that implement __getitem__
. Iterable objects implement __iter__
所以在语言层面这些概念并不直接相关
话虽如此,最常见的 容器 如列表或字典都是可迭代和可订阅的。但是 set
是可迭代且不可订阅的容器的示例,同样,生成器生成可迭代且不可订阅的对象。
我没有可剥离但不可迭代对象的通用示例,但很容易想象一个特殊的 class 可以验证它。极端情况是,如果下标可以是整数,则该对象将不是真正的可迭代对象(不能在其上使用 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
What is the difference between subscriptable and iterable objects ?
可订阅对象实现 __getitem__
并因此计算 obj[key]
语法。
可迭代对象实现 __iter__
,因此支持迭代。
What are the objects which are subscriptable but not iterable
一个例子是 re.match()
,其中 returns 一个不可迭代的可订阅对象。
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)
and vice versa?
一个例子是set
,它支持迭代但不支持订阅。所以你可以做:
for x in set([42]):
print(x) # 42
...但这会产生错误:
set([42])[0] # TypeError: 'set' object is not subscriptable
可订阅和可迭代 对象之间的区别是什么? 什么是可订阅但不可迭代的对象,反之亦然?
P.s。可订阅的是其中包含其他对象的对象,迭代器是可订阅的,可以迭代。但我能想到的也仅此而已。
正如@juanpa.arrivillaga 在他的评论中所说:
Subscriptable objects are objects that implement
__getitem__
. Iterable objects implement__iter__
所以在语言层面这些概念并不直接相关
话虽如此,最常见的 容器 如列表或字典都是可迭代和可订阅的。但是 set
是可迭代且不可订阅的容器的示例,同样,生成器生成可迭代且不可订阅的对象。
我没有可剥离但不可迭代对象的通用示例,但很容易想象一个特殊的 class 可以验证它。极端情况是,如果下标可以是整数,则该对象将不是真正的可迭代对象(不能在其上使用 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
What is the difference between subscriptable and iterable objects ?
可订阅对象实现
__getitem__
并因此计算obj[key]
语法。可迭代对象实现
__iter__
,因此支持迭代。
What are the objects which are subscriptable but not iterable
一个例子是 re.match()
,其中 returns 一个不可迭代的可订阅对象。
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)
and vice versa?
一个例子是set
,它支持迭代但不支持订阅。所以你可以做:
for x in set([42]):
print(x) # 42
...但这会产生错误:
set([42])[0] # TypeError: 'set' object is not subscriptable