2017-06-12 5 views
4

itertools.groupbyをPythonで使う方法を学びたいと思っていて、それぞれの文字グループのサイズを探したかったのです。最初に私は単一のグループの長さを見つけることができるかどうかを試しました:itertools "grouper"オブジェクトをリストにする方法

from itertools import groupby 
len(list(list(groupby("cccccaaaaatttttsssssss"))[0][1])) 

そして毎回0を得るでしょう。

私は少し研究を行なったし、他の人がそれをこのようにやっていたことが判明:素晴らしい作品

from itertools import groupby 
for key,grouper in groupby("cccccaaaaatttttsssssss"): 
    print key,len(list(grouper)) 

を。私が混乱しているのは、後者のコードはなぜ機能するのですが、前者はなぜですか?私が元のコードでやろうとしていたように、n番目のグループだけを取得したいのであれば、どうすればいいのですか?

答えて

4

動作しません、あなたの最初のアプローチは、あなたが返されるグループがあるthe groupby docs

から引用すると

list(groupby("cccccaaaaatttttsssssss")) 

と、そのリストを作成するときのグループが「消費」を得ることである理由それ自体は、 を反復可能で、groupby()で共有するイテレータです。ソースが共有されているため、 groupby()オブジェクトがアドバンスされている場合、前のグループはもはや が表示されなくなります。

ステージに分割しましょう。

from itertools import groupby 

a = list(groupby("cccccaaaaatttttsssssss")) 
print(a) 
b = a[0][1] 
print(b) 
print('So far, so good') 
print(list(b)) 
print('What?!') 

出力

[('c', <itertools._grouper object at 0xb715104c>), ('a', <itertools._grouper object at 0xb715108c>), ('t', <itertools._grouper object at 0xb71510cc>), ('s', <itertools._grouper object at 0xb715110c>)] 
<itertools._grouper object at 0xb715104c> 
So far, so good 
[] 
What?! 

それがgroupbyによって返された「親」イテレータと、その内容を共有するために私たちのitertools._grouper object at 0xb715104cが空で、その最初のlist通話がかけ反復するので、これらのアイテムは、現在なくなっています親。

単純なジェネレータ式のように、どのイテレータでも2回反復しようとすると、どうなるでしょうか。

g = (c for c in 'python') 
print(list(g)) 
print(list(g)) 

出力

['p', 'y', 't', 'h', 'o', 'n'] 
[] 

はところで、ここにあなたが実際にその内容を必要としない場合groupbyグループの長さを取得する別の方法です。それはちょうどその長さを見つけるためにリストを構築するよりも少し安いです(そして、より少ないRAMを使用します)。

from itertools import groupby 

for k, g in groupby("cccccaaaaatttttsssssss"): 
    print(k, sum(1 for _ in g)) 

出力

c 5 
a 5 
t 5 
s 7 
+0

これは偉大な説明です。本当にありがとう! – cafemolecular

関連する問題