【发布时间】:2017-03-20 22:57:48
【问题描述】:
所以我正在探索 itertools.combinations 背后的代码。在文档中,它给出了“等效”,如下所示:
def combinations(iterable, r):
# combinations('ABCD', 2) --> AB AC AD BC BD CD
# combinations(range(4), 3) --> 012 013 023 123
pool = tuple(iterable)
n = len(pool)
if r > n:
return
indices = range(r)
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
if indices[i] != i + n - r:
break
else:
return
indices[i] += 1
for j in range(i+1, r):
indices[j] = indices[j-1] + 1
yield tuple(pool[i] for i in indices)
假设我有一个列表:
sequence = [1,2,3,4,5,6,7,8,9,10]
和:
r=3
我尝试将生成器转换为列表,然后打印它,但我得到了:
print(list(combinations(sequence,3)))
...
---> 16 indices[i] += 1
17 for j in range(i+1, r):
18 indices[j] = indices[j-1] + 1
TypeError: 'range' object does not support item assignment
我无法修改它以使其正常工作而不会导致更多错误。 如果有人可以为我提供一些关于如何解决此 TypeError 的指导,我将不胜感激。
简而言之,我想知道为什么这样做可行,但之前的代码却不行:
print(list(itertools.combinations(sequence,3)))
[(1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 2, 6), (1, 2, 7) ...]
【问题讨论】:
-
你应该看看the 3.x documentation,你正在尝试的版本是2.x。或者,正如您在询问之前应该做的那样,搜索错误消息:stackoverflow.com/q/9091044/3001761、stackoverflow.com/q/20484195/3001761、stackoverflow.com/q/16435607/3001761
-
具体来说,在 3.x 中,
range返回一个生成器而不是一个列表(就像在 2.x 中所做的那样)。 3.x 等效项首先将其强制放入列表中:indices = list(range(r))。 docs.python.org/3/library/itertools.html#itertools.combinations -
@PeterDeGlopper:Python 3
range不返回生成器。它返回一个惰性序列对象。特别是,它是一个真实的序列,支持索引和切片,并且您可以反复迭代单个range对象。 -
谢谢,我对那个评论很草率。
标签: python python-3.x