Python 计数器 class for 循环中的行为与理解

Python Counter class behaviour in for loop versus comprehension

有人可以解释为什么计数器 class 的行为在循环中与在理解中使用时会发生变化吗?下面是一个简单的例子:

>>> seqs = ["GATAGCTCGC", "GTAGAGCTCGCTC", "GTATATAGCTCGCCTG"]
>>> import collections
>>> counts1 = collections.Counter()
>>> for seq in seqs:
...     counts1.update(seq)
... 
>>> counts1
Counter({'G': 11, 'C': 11, 'T': 10, 'A': 7})
>>> counts2 = collections.Counter(seq for seq in seqs)
>>> counts2
Counter({'GTAGAGCTCGCTC': 1, 'GATAGCTCGC': 1, 'GTATATAGCTCGCCTG': 1})

为什么更新方法将输入的字符串拆分为字符并计算字符而不是整个字符串对象?我怎样才能在 for 循环中获得后一种行为?

update() 期望一个可迭代对象并尝试对其进行迭代,字符串是可迭代对象:

for seq in seqs:
    counts1.update(seq)

seqGATAGCTCGC 并将用作 ['G', 'A', 'T' ....]


要有相同的行为,给它一个列表:

for seq in seqs:
    counts1.update([seq])

字符串、列表和其他东西在 Python 中是“iterables”,这意味着它们可以循环。在 for 循环中,您将每个单独的字符串传递给 counts1.update()。由于字符串是可迭代的,counts1.update() 遍历字符串 character-by-character,计算单个字符。

在列表推导式seq for seq in seqs中,列表推导式本身是一个提供三个元素的可迭代对象。 collections.Counter() 遍历给定的迭代器,它只有三个元素,并对每个元素进行计数。

使用 update 传递一个遍历的可迭代对象并对值进行计数。由于 str 被认为是可迭代的,因此每个字符都作为一个单独的元素出现,因此被计算在内。

在构造函数的情况下,可迭代对象由整个字符串组成,因此将计算字符串而不是它们组成的字符。