(我是Python的新手,所以即使阅读完教程后,很多东西也让我感到困惑......)
最初,我有以下代码:
strings = ['>abc', 'qwertyu', '>def', 'zxcvbnm']
matrix = zip(*strings)
for member in matrix:
print("".join(member)) # characters are printed as expected
- 这符合我的预期。但由于某种原因,我想确定矩阵中的成员数量;由于len(矩阵)给出了错误,我决定将其复制到转换为列表:mtxlist = list(matrix)
。令人惊讶的是,在这一行之后,矩阵的内容似乎发生了变化 - 或者至少我不能像上面那样使用它:
strings = ['>abc', 'qwertyu', '>def', 'zxcvbnm']
matrix = zip(*strings)
mtxlist = list(matrix) # this assignment empties (?) the matrix
for member in matrix:
print("".join(member)) # nothing printed
有人可以解释那里发生了什么吗?
答案 0 :(得分:8)
你正在使用Python 3,对吗?
zip
返回一个只能迭代一次的生成器。如果您想多次使用它,那么您的选择是:
每次需要时写zip(*strings)
。
matrix = tuple(zip(*strings))
(根据需要迭代matrix
。这是一个简单的选择。缺点是如果zip(*strings)
很大,那么它会占用发电机所没有的大量内存。)
matrix1, matrix2 = itertools.tee(zip(*strings))
(迭代matrix1
和matrix2
中的每一个。这比您使用中的tuple
更糟糕,但如果您想部分消耗matrix1
,那么它很有用使用部分matrix2
,更多matrix1
等等)
def matrix():
return zip(*strings)
# or
matrix = lambda: zip(*strings)
(迭代但是使用matrix()
,而不是matrix
,你可以多次使用。不使用额外的内存来获得tuple
解决方案的结果副本,但是使用它的语法有点烦人)
class ReusableIterable:
def __init__(self, func):
self.func = func
def __iter__(self):
return iter(self.func())
matrix = ReusableIterable(lambda: zip(*strings))
(尽可能多次使用matrix
进行迭代。处理语法烦恼,尽管您仍需要注意,如果您在strings
之间的迭代之间修改matrix
,那么你'会得到不同的结果。)