Python的list()函数修改了它的参数?

时间:2013-11-23 09:20:14

标签: python

(我是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

有人可以解释那里发生了什么吗?

1 个答案:

答案 0 :(得分:8)

你正在使用Python 3,对吗?

zip返回一个只能迭代一次的生成器。如果您想多次使用它,那么您的选择是:

每次需要时写zip(*strings)

matrix = tuple(zip(*strings))

(根据需要迭代matrix。这是一个简单的选择。缺点是如果zip(*strings)很大,那么它会占用发电机所没有的大量内存。)

matrix1, matrix2 = itertools.tee(zip(*strings))

(迭代matrix1matrix2中的每一个。这比您使用中的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,那么你'会得到不同的结果。)