12

次のようなリストのリストがあります。

[[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番目の要素の最低値を見つけようとしています(したがって、 15 と 13 と 18 を比較し、 10564 と 15 を比較しません)が、それを範囲に分割するため、最低の2番目の要素と言えます[1]各リストで、要素 [0] が 10000 を超える場合などにのみ。これを行うにはどうすればよいですか? 私はそれを試してみましたが、まだ同じリスト内の要素しか比較できません。これは私が望むものではありません。私が言及した場合、私は [10787, 9] を返しますが、9 で 10000 を超える別の値があった場合は、それも返したいと思います。

4

5 に答える 5

14

これは、出力に必要なものによって異なります。まず、「範囲」に基づいてリストをフィルタリングする必要があります1

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

条件は、if(有効な構文内で) 必要に応じて複雑にすることができます。例えば:

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

全然大丈夫です。


ここで、サブリストの 2 番目の要素のみが必要な場合:

min(x[1] for x in gen)

もちろん、全体をインライン化することもできます:

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

サブリスト全体が必要な場合:

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)]

一致する数よりも少ないことが確実にわかっている場合は、 andNを使用してこれをもう少し効率的に行うことができます。一致数の上限がわからない一般的なケースでは、このソリューションの方が優れていると思います (O(NlogN) である並べ替えと比較して O(N) です)。heapqitertools.takewhile


1「ジェネレーター式」は、使い果たされる前に 1 回しか反復できないことに注意してください。

于 2013-04-16T12:24:33.920 に答える
4
>>> 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]
于 2013-04-16T12:26:03.540 に答える
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]
于 2013-04-16T12:29:37.600 に答える
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[0]、最初のものvals[1]を取得したり、2番目のものを取得したり、次のようなスライスを使用したりできvals[:5]ます...

于 2013-04-16T12:46:17.840 に答える
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)))
于 2013-04-16T12:24:14.773 に答える