文档地址:https://docs.python.org/zh-cn...
class groupby:
# [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
def __init__(self, iterable, key=None):
if key is None:
key = lambda x: x
self.keyfunc = key
self.it = iter(iterable)
self.tgtkey = self.currkey = self.currvalue = object()
def __iter__(self):
return self
def __next__(self):
self.id = object()
while self.currkey == self.tgtkey:
self.currvalue = next(self.it) # Exit on StopIteration
self.currkey = self.keyfunc(self.currvalue)
self.tgtkey = self.currkey
return (self.currkey, self._grouper(self.tgtkey, self.id))
def _grouper(self, tgtkey, id):
while self.id is id and self.currkey == tgtkey:
yield self.currvalue
try:
self.currvalue = next(self.it)
except StopIteration:
return
self.currkey = self.keyfunc(self.currvalue)
请问 _grouper里面,while self.id is id,,在什么情况下会出现 self.id is not id 的情况呢?
groupby 本身是一个迭代器,每次迭代出的元组第二个元素是生成器,所以它有个设计约束,必须要顺序迭代展开每个生成器,像下面这样。
再看不按顺序迭代的情况
先迭代gs2后,gs1已经失效了,这是设计约束,这个约束是通过
_grouper
的第一行达到的:仅靠
self.currkey == tgtkey
不足以约束,如我给出的数据为例,lst 没有按 'country' 排序, 所以在迭代groupby 的对象时, 'China', 'USA' 这样的key都会两次出现。所以self.id是必须的标记。