为了正确理解这一点,首先请确保您了解相关的基础知识:Python的iterator protocol和object identity versus equality。
当传递iterator而不是iterable时,我无法理解python中zip()
函数的工作方式。
看看这两个打印语句:
string = "ABCDEFGHI"
print(list(zip(*[iter(string)] * 3)))
# Output: [('A', 'B', 'C'), ('D', 'E', 'F'), ('G', 'H', 'I')]
print(list(zip(*[string] * 3)))
# Output: [('A', 'A', 'A'), ('B', 'B', 'B'), ('C', 'C', 'C'), ('D', 'D', 'D'), ('E', 'E', 'E'), ('F', 'F', 'F'), ('G', 'G', 'G'), ('H', 'H', 'H'), ('I', 'I', 'I')]
有人可以在两种情况下解释我zip()的工作吗?
区别在于,对于[iter(string)] * 3
,zip
创建单个迭代器的别名。对于[string] * 3
,zip
为每个参数创建唯一的迭代器。没有重复的较短输出是zip
耗尽了单个别名迭代器。
有关what is meaning of [iter(list)]*2 in python?的工作方式以及可能导致意想不到的结果的更多详细信息,请参见[iter(...)] * 2
。>
如果List of lists changes reflected across sublists unexpectedly混叠行为令人惊讶,请参阅规范答案[...] * 3
。>
为了正确理解这一点,首先请确保您了解相关的基础知识:Python的iterator protocol和object identity versus equality。
print(list(zip(*[string] * 3)))
我们计算列表[string] * 3
,并将该列表中的每个元素传递给zip
,因此就好像我们编写了zip(string, string, string)
一样。 Python为每个参数隐式创建一个单独的迭代器(即使在每种情况下它都是相同的字符串对象-不能复制!),并且每个参数都对同一字符串进行迭代。第一次,每个迭代器都会找到'A'
,依此类推。
print(list(zip(*[iter(string)] * 3)))
现在,我们为字符串创建了一个迭代器,并将其在三个参数位置传递给zip
。在每种情况下,Python的迭代逻辑都会尝试为该迭代器“创建一个迭代器”。但是迭代器的迭代器本身就是
zip
将使用相同的迭代器对象3次来创建其每个输出。并且每次它从迭代器中获取next
元素时,都会受到先前尝试的影响。因此,第一次,zip
向同一迭代器请求三个元素,并获得'A'
,'B'
和'C'
。 让我们使用一个更清晰的示例:
a = iter("123456") # One iterator
list(zip(a, a, a))
# [('1', '2', '3'), ('4', '5', '6')]
vs
a = iter("123456")
b = iter("123456")
c = iter("123456")
list(zip(a, b, c))
# [('1', '1', '1'), ('2', '2', '2'), ('3', '3', '3'), ('4', '4', '4'), ('5', '5', '5'), ('6', '6', '6')]
显然,在第一个示例中,a
只能产生6个元素,并且每当zip
需要创建值时,都必须产生3到zip
。相比之下,第二个示例总共有18个元素,并以3为6组的形式产生它们。
为了正确理解这一点,首先请确保您了解相关的基础知识:Python的iterator protocol和object identity versus equality。
让我们使用一个更清晰的示例: