45

「平均」と呼ばれる 1 から 5 までの浮動小数点数の長いリストがあり、a より小さいか b より大きい要素のインデックスのリストを返したい

def find(lst,a,b):
    result = []
    for x in lst:
        if x<a or x>b:
            i = lst.index(x)
            result.append(i)
    return result

matches = find(average,2,4)

しかし驚くべきことに、「matches」の出力には多くの繰り返しが含まれてい[2, 2, 10, 2, 2, 2, 19, 2, 10, 2, 2, 42, 2, 2, 10, 2, 2, 2, 10, 2, 2, ...]ます。

なぜこうなった?

4

3 に答える 3

70

リスト内で最初に出現する値.index()のみを検索する which を使用しています。したがって、インデックス 2 とインデックス 9 に値 1.0 がある場合、リスト内で何回発生しても、は常に を返します。.index(1.0)21.0

enumerate()代わりに、ループにインデックスを追加するために使用します。

def find(lst, a, b):
    result = []
    for i, x in enumerate(lst):
        if x<a or x>b:
            result.append(i)
    return result

これをリスト内包表記にまとめることができます:

def find(lst, a, b):
    return [i for i, x in enumerate(lst) if x<a or x>b]
于 2013-05-22T07:02:32.273 に答える
3

この種のことをたくさん行っている場合は、 の使用を検討する必要がありますnumpy

In [56]: import random, numpy

In [57]: lst = numpy.array([random.uniform(0, 5) for _ in range(1000)]) # example list

In [58]: a, b = 1, 3

In [59]: numpy.flatnonzero((lst > a) & (lst < b))[:10]
Out[59]: array([ 0, 12, 13, 15, 18, 19, 23, 24, 26, 29])

Seanny123 の質問に応えて、次のタイミング コードを使用しました。

import numpy, timeit, random

a, b = 1, 3

lst = numpy.array([random.uniform(0, 5) for _ in range(1000)])

def numpy_way():
    numpy.flatnonzero((lst > 1) & (lst < 3))[:10]

def list_comprehension():
    [e for e in lst if 1 < e < 3][:10]

print timeit.timeit(numpy_way)
print timeit.timeit(list_comprehension)

numpy バ​​ージョンは 60 倍以上高速です。

于 2016-05-16T23:09:13.710 に答える
-1
>>> average =  [1,3,2,1,1,0,24,23,7,2,727,2,7,68,7,83,2]
>>> matches = [i for i in range(0,len(average)) if average[i]<2 or average[i]>4]
>>> matches
[0, 3, 4, 5, 6, 7, 8, 10, 12, 13, 14, 15]
于 2013-05-22T07:03:50.487 に答える