grouper レシピを使用してizip(*[iterator]*2)
、行を 2 つのグループにクラスター化できます。次に、行df
の最小ペアを見つけるには、min
とそのkey
パラメーターを使用して、比較に使用するプロキシを指定します。この場合、行のペアごと(p, l)
に、2 番目の行の float をfloat(l)
プロキシとして使用します。
import itertools as IT
with open('filepath') as df:
previous, minline = min(IT.izip(*[df]*2),
key=lambda (p, l): float(l))
minline = float(minline)
print(previous)
print(minline)
版画
Over
0.5678
ハタのレシピの説明:
ハタのレシピを理解するには、まずdf
リストの場合に何が起こるかを見てください。
In [1]: df = [1, 2]
In [2]: [df]*2
Out[2]: [[1, 2], [1, 2]]
Python では、リストに正の整数を掛けると、リスト内の項目の (浅い) コピーがn
取得されます。n
したがって、内部[df]*2
の 2 つのコピーを持つリストを作成します。df
今考えますzip(*[df]*2)
*
inにはzip(*...)
特別な意味があります。*
に渡される into 引数に続くリストをアンパックするように Python に指示しzip
ます。したがって、zip(*[df]*2)
は とまったく同じですzip(df, df)
:
In [3]: zip(df, df)
Out[3]: [(1, 1), (2, 2)]
In [4]: zip(*[df]*2)
Out[4]: [(1, 1), (2, 2)]
引数のアンパッキングのより完全な説明は、SaltyCrane here によって提供されます。
行っていることzip
に注意してください。
zip(*[df]*2)
両方のコピーの最初の要素 (この場合は両方とも 1) を剥がし、タプル (1,1) を形成します。次に、両方のコピーの 2 番目の要素 (両方とも 2) を剥がし、タプル (2,2) を形成します。これらのタプルを内部に含むリストを返します。
df
がイテレータの場合に何が起こるかを考えてみましょう。イテレータはリストに似ていますが、イテレータは 1 回のパスのみに適しています。アイテムはイテレータから引き出されるため、イテレータを巻き戻すことはできません。
たとえば、ファイル ハンドルは反復子です。行を含むファイルがあるとします
1
2
3
4
In [8]: f = open('data')
f
次のように呼び出すことで、イテレータから項目を取り出すことができますnext(f)
。
In [9]: next(f)
Out[9]: '1\n'
In [10]: next(f)
Out[10]: '2\n'
In [11]: next(f)
Out[11]: '3\n'
In [12]: next(f)
Out[12]: '4\n'
を呼び出すたびにnext(f)
、ファイル ハンドルから次の行を取得しますf
。もう一度呼び出すとnext(f)
、反復子が空であることを示す StopIteration 例外が発生します。
次に、グルーパー レシピが でどのように動作するかを見てみましょうf
。
In [14]: f = open('data') # Notice we have to open the file again, since the old iterator is empty
In [15]: [f]*2
Out[15]:
[<open file 'data', mode 'r' at 0xa028f98>,
<open file 'data', mode 'r' at 0xa028f98>]
[f]*2
は、同じ iterator の2 つの同一のコピーを含むリストを返しますf
。
In [16]: zip(*[f]*2)
Out[16]: [('1\n', '2\n'), ('3\n', '4\n')]
zip(*[f]*2)
最初のイテレータ から最初のアイテムをf
剥がし、次に 2 番目のイテレータ から最初のアイテムを剥がしますf
。しかし、イテレータはf
両方とも同じです! また、反復子は 1 回のパスに適しているため (元に戻ることはできません)、アイテムを剥がすたびに異なるアイテムが得られます。アイテムを剥がすために毎回zip
呼び出しています。next(f)
したがって、最初のタプルは
('1\n', '2\n')
. 同様にzip
、最初の iterator から次のアイテムを剥がしf
、2 番目の iterator から次のアイテムを剥がしてf
、タプルを形成し('3\n', '4\n')
ます。したがって、 をzip(*[f]*2)
返します
[('1\n', '2\n'), ('3\n', '4\n')]
。
ハタのレシピはこれで全部です。上記では、Python がタプルのリストではなく反復子を返すように、IT.izip
代わりに使用することを選択しました。zip
ファイルに多くの行が含まれている場合、これにより多くのメモリが節約されます。との違いについてはzip
、こちらでIT.izip
詳しく説明しています。