タプルの内容が番号9
であり、リスト内でその前の番号であるタプルのリストを作成しようとしています。
入力リスト:
myList = [1, 8, 9, 2, 4, 9, 6, 7, 9, 8]
目的の出力:
sets = [(8, 9), (4, 9), (7, 9)]
コード:
sets = [list(Zip(myList[i:i], myList[-1:])) for i in myList if i==9]
現在の結果:
[[], [], []]
よりクリーンなPythonicアプローチ:
_>>> [(x,y) for x,y in Zip(myList, myList[1:]) if y == 9]
[(8, 9), (4, 9), (7, 9)]
_
上記のコードは何をしていますか:
Zip(some_list, some_list[1:])
は、隣接する要素のペアのリストを生成します。9
_に等しいという条件でフィルタリングします。完了です:)問題の一部は、myList[i:i]
が常に空のリストを返すことです。スライスの終わりは排他的であるため、a_list[0:0]
を実行すると、存在するa_list
の要素を取得しようとしますbetween index0とindex0。
あなたは正しい方向に進んでいますが、リストをそれ自体で圧縮したいと考えています。
[(x, y) for x, y in Zip(myList, myList[1:]) if y==9]
あなたはかなり近かったので、始めたばかりの場合はもっと直感的な別の方法を紹介します。
_sets = [(myList[i-1], myList[i]) for i in range(len(myList)) if myList[i] == 9]
_
リストの長さの範囲内のインデックスを取得し、位置i
の値が_9
_と等しい場合は、隣接する要素を取得します。
結果は次のとおりです。
_sets
[(8, 9), (4, 9), (7, 9)]
_
これは他のアプローチよりも効率が悪いですが、別の方法を示すために削除を取り消すことにしました。代わりにenumerate()
を使用すると、少し速く進むことができます。
_sets = [(myList[i-1], j) for i, j in enumerate(myList) if j == 9]
_
注意その_myList[0] = 9
_Zip
なしの理解の振る舞いとZip
の理解度はdifferentです。
具体的には、_myList = [9, 1, 8, 9, 2, 4, 9, 6, 7, 9, 8]
_の場合:
_[(myList[i-1], myList[i]) for i in range(len(myList)) if myList[i] == 9]
# results in: [(8, 9), (8, 9), (4, 9), (7, 9)]
_
一方:
_[(x, y) for x, y in Zip(myList, myList[1:]) if y==9]
# results in: [(8, 9), (4, 9), (7, 9)]
_
これらのどれがあなたの基準に合うかを決めるのはあなた次第です、私はそれらがすべての場合に同じように振る舞うわけではないことを指摘しているだけです。
誰も機能的なアプローチを追加していないのは本当に驚くべきことです。
別の代替回答は filter
を使用することです。この組み込み関数は、特定の関数に対してTrue
を返すリストに存在するすべての要素で構成されるイテレーター(Python2のリスト)を返します。
>>> myList = [1,8,9,2,4,9,6,7,9,8]
>>> list(filter(lambda x:x[1]==9,Zip(myList, myList[1:])))
[(8, 9), (4, 9), (7, 9)]
list
呼び出しはpython3 + でのみ必要であることに注意してください。機能的アプローチとリスト内包表記の違いについては、 この投稿の詳細 で説明しています。
イテレータを作成することで、スライスせずにそれを行うこともできます。
l = myList = [1,8,9,2,4,9,6,7,9,8]
it1, it2 = iter(l), iter(l)
# consume first element from it2 -> leaving 8,9,2,4,9,6,7,9,8
next(it2, "")
# then pair up, (1,8), (8,9) ...
print([(i, j) for i,j in Zip(it1, it2) if j == 9])
または、 ペアワイズレシピ を使用してペアを作成します
from itertools import tee, izip
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
Python3を使用している場合は、teeをインポートし、通常のZipを使用します。
私のソリューションは、ゼロインデックスチェックを備えたジムの高度なソリューションの1つに似ています
myList = [9, 1, 8, 9, 2, 4, 9, 6, 7, 9, 8]
[(myList[i-1], x) for i, x in enumerate(myList) if x==9 and i!=0]
# [(8, 9), (4, 9), (7, 9)]