最小

2013-04-16 10 views
6

私はそうのようなリストのリストを持っている:最小

[[10564, 15], [10564, 13], [10589, 18], [10637, 39], [10662, 38], [10712, 50], [10737, 15], [10762, 14], [10787, 9], [10812, 12], [10837, 45], [3, 17], [7, 21], [46, 26], [48, 12], [49, 24], [64, 14], [66, 
17], [976, 27], [981, 22], [982, 22], [983, 17], [985, 13], [517, 9], [521, 15], [525, 11], [526, 13], [528, 14], [698, 14], [788, 24], [792, 19]] 

私は、各リストの2番目の要素の最小値を見つけようとしています(その18に13に等の比較ではないが15を比較10564と15)だけでなく、それを範囲に分けることもできるので、要素[0]が10000を超えている場合にのみ、各リストの中で最も低い第2要素[1]と言うことができます。私はそれを試してみて、同じリストの要素をまだ比較することができます。これは私が望むものではありません。私が言及した場合、私は[10787、9]を返すだろうと言いましたが、10000を超える値が9であれば、それも返したいと思います。

答えて

9

出力する内容によって異なります。まず、あなたはif条件は(有効な構文の中に)あなたが望むように複雑になることが「範囲」

gen = (x for x in lists if x[0] > 10000) 

に基づいてリストをフィルタリングする必要があります。例:

gen = (x for x in lists if 5000 < x[0] < 10000) 

完全に問題ありません。あなたがサブリストからのみ第二の要素たい場合


今、:あなたは全体のサブリストをしたい場合は

min(x[1] for x in lists if x[0] > 10000) 

:もちろん

min(x[1] for x in gen) 

を、あなたは全部をインライン可能性:

from operator import itemgetter 
min(gen,key=itemgetter(1)) 

例:

>>> lists = [[10564, 15], [10564, 13], [10589, 18], [10637, 39], [10662, 38], [10712, 50], [10737, 15], [10762, 14], [10787, 9], [10812, 12], [10837, 45], [3, 17], [7, 21], [46, 26], [48, 12], [49, 24], [64, 14], [66,17], [976, 27], [981, 22], [982, 22], [983, 17], [985, 13], [517, 9], [521, 15], [525, 11], [526, 13], [528, 14], [698, 14], [788, 24], [792, 19]] 
>>> gen = (x for x in lists if x[0] > 10000) 
>>> min(x[1] for x in gen) 
9 
>>> gen = (x for x in lists if x[0] > 10000) 
>>> from operator import itemgetter 
>>> min(gen,key=itemgetter(1)) 
[10787, 9] 

残念ながら、これらはあなたの基準に一致する最初サブリストを与えます。それらのすべてを取得するには:

target = min(x[1] for x in lists if x[0] > 10000) 
matches = [x for x in lists if (x[1] == target) and (x[0] > 10000)] 

を使用すると、以下のNマッチが存在することを確実にわかっている場合は、heapqitertools.takewhileでより効率的に、この小さなを行うことができます。一致数の上限がわからない一般的なケースでは、この解決策はより良いと思います(ソートと比較してO(N)ですが、O(NlogN)です)。


それはあなたのコメントのための

+0

すばらしい答え。うん、帰りたい[10787、9] itemgetterを読んだ。私は、ジェネレータの表現が枯渇しているということに従わない。何らかの理由でそれをもう一度繰り返すことはできないのですか? – Paul

+0

@Paul - そうです。ジェネレータは一度しか反復できません。通常これは問題ではありません(別のものを作成することはできます)。しかし、問題がある場合は、代わりにリストの理解を使うことができます: 'lst = [x [0]> 10000ならリストのxのx ')' – mgilson

+0

ああ、完璧です。ありがとう。リストの理解に詳しい私は括弧とは別の違いを見ることができない、私はジェネレータとの違いに読んでいる必要があります、ありがとう。 – Paul

1
a=[[10564, 15], [10564, 13], [10589, 18], [10637, 39], [10662, 38], [10712, 50], [10737, 15], [10762, 14], [10787, 9], [10812, 12], [10837, 45], [3, 17], [7, 21], [46, 26], [48, 12], [49, 24], [64, 14], [66, 17], [976, 27], [981, 22], [982, 22], [983, 17], [985, 13], [517, 9], [521, 15], [525, 11], [526, 13], [528, 14], [698, 14], [788, 24], [792, 19]] 

print min(map(lambda y: y[1] ,filter(lambda x: x[0]>10000,a))) 
+0

ありがとう、これを理解するために実行します。 – Paul

2
>>> l=[[10564, 15], [10564, 13], [10589, 18], [10637, 39]] 
>>> min(x[1] for x in l if x[0] > 10000) 
13 
>>> 

更新を排出される前に、「ジェネレータ式は」唯一の(あなたが最小機能でキーのラムダを使用することができ、一度巡回できないことに注意してください、itemgetterは大きなリストで少し速くなります):

>>> min((x for x in l if x[0] > 10000), key=lambda k:k[1]) 
[10564, 13] 
+0

ありがとう、シンプルなので、私はこの場合[10564、13]を返したいと思います。 – Paul

+0

'x [0]> 10000 'のどれも保持していなければ、ValueError:min()argが空のシーケンスであるという点を除いて、これは私のお気に入りです。だから、これを 'try: - except'ブロックで囲む必要があります。あなたが' min'のセンチネル値に潜入する方法を見つけることができなければ(私は簡単だとは思わない) –

+0

@Paul 'x [0]'と 'x [1]'を解凍し、記述的な名前をつけることを考えてください。 'min(スコアのid、score> 10000の場合はid)'である可能性があります。 –

4

最小値を見つけて、その値に基づいてリストを構築します。

>>> a = [[10564, 15], [10564, 13], [10589, 18], [10637, 39], [10662, 38], [10712, 50], [10737, 15], [10762, 14], [10787, 9], [10812, 12], [10837, 45], [3, 17], [7, 21], [46, 26], [48, 12], [49, 24], [64, 14], [66, 
... 17], [976, 27], [981, 22], [982, 22], [983, 17], [985, 13], [517, 9], [521, 15], [525, 11], [526, 13], [528, 14], [698, 14], [788, 24], [792, 19]] 
>>> a_min = min(i[1] for i in a) 
>>> [i[0] for i in a if i[1] == a_min and i[0] > 10000] + [a_min] 
[10787, 9] 

コードが正しく、複数の値を表示します。

>>> a += [[10391, 9]] #add another pair with a first value > 10000 
>>> [i[0] for i in a if i[1] == a_min and i[0] > 10000] + [a_min] 
[10787, 10391, 9] 
+0

非常にいいです、私はすべての可能な等しい値のその小さなリストが好きです! – Paul

+0

私はむしろ 'a + = [lst]'よりむしろ 'a.append(lst)'と書いていると思います – mgilson

+0

また、なぜ: 'i [1] == a_minとi [ '[i] == a_minとi [0]> 10000]の場合はiの代わりに' 0 '> 10000] + [a_min] 'を返します。 – mgilson

2

複数minのが必要な場合は、おそらくあなたは、該当する要素をフィルタリングし、それらをソートする最善だ...

vals = sorted((el for el in your_list if el[0] >= 10000), key=lambda L: L[1]) 
# [[10787, 9], [10812, 12], [10564, 13], [10762, 14], [10564, 15], [10737, 15], [10589, 18], [10662, 38], [10637, 39], [10837, 45], [10712, 50]] 

その後、最初にを取得し、vals[1]を取得するか、vals[:5]などのスライシングを使用することができます。 ..

+0

' Counter.least_common'メソッド... – mgilson

+0

ここでは 'itertools.takewhile'を使って' L [2] == vals [0] [1] ' – mgilson