5

Python クラスを始めたばかりで、本当に助けが必要です。あなたがこれに答えているなら、私は新しいことを覚えておいてください。

特定のリスト "l" 内のすべての要素の平均をとるプログラムを作成する必要があります。それ自体は非常に簡単な機能です。問題は、教師が平均を行う前に、リストにある空の文字列を削除することを望んでいることです。

したがって、リストを受け取っ[1,2,3,'',4]たら、関数が平均を無視し''、他の 4/len(l) の平均を取るようにします。誰でもこれで私を助けることができますか?

おそらく、リストの特定の位置を と比較し続け、''それらをリストから削除するサイクルでしょうか? 私はそれを試しましたが、うまくいきません。

4

7 に答える 7

13

リスト内包表記を使用して、次のすべての要素を削除できます''

mylist = [1, 2, 3, '', 4]
mylist = [i for i in mylist if i != '']

次に、合計を取得してリスト内の要素数で割ることにより、平均を計算できます。

avg = sum(mylist)/len(mylist)

浮動小数点平均(Python 2を想定)

アプリケーションによっては、平均をintではなくfloatにしたい場合があります。その場合は、最初にこれらの値の1つをfloatにキャストします。

avg = float(sum(mylist))/len(mylist)

または、Python3の分割を使用することもできます。

from __future__ import division
avg = sum(mylist)/len(mylist)
于 2012-10-30T12:33:53.887 に答える
7

使用できますfilter()

filter()listリストを渡すと Python 2 でa を返し、iteratorPython 3 で an を返します。@PhilH で提案されているよう itertools.ifilter()に、Python 2 でイテレータを取得するために使用できます。

Python 3 でリストを出力として取得するには、次を使用します。list(filter(lambda x:x != '', lis))

In [29]: lis = [1, 2, 3, '', 4, 0]

In [30]: filter(lambda x:x != '', lis)
Out[30]: [1, 2, 3, 4, 0]

単純に使用できる偽の値をフィルタリングすることに注意してくださいfilter(None, ...)

>>> lis = [1, 2, 3, '', 4, 0]
>>> filter(None, lis)
[1, 2, 3, 4]
于 2012-10-30T12:49:12.913 に答える
2
itertools.ifilterfalse(lambda x: x=='', myList)

これは反復子を使用するため、リストのコピーを作成せず、時間とメモリの両方でより効率的であり、長いリストに対して堅牢になります。

JonClements は、これは長さを個別に追跡することを意味すると指摘しているので、そのプロセスを示します。

def ave(anyOldIterator):
    elementCount = 0
    runningTotal = 0
    for element in anyOldIterator:
        runningTotal += element
        elementCount += 1
    return runningTotal/elementCount

またはさらに良い

def ave(anyOldIterator):
    idx = None
    runningTotal = 0
    for idx,element in enumerate(anyOldIterator):
        runningTotal += element
    return runningTotal/(idx+1)

減らす:

def ave(anyOldIterator):
    pieces = reduce(lambda x,y: (y[0],x[1]+y[1]), enumerate(anyOldIterator))
    return pieces[1]/(pieces[0]+1)

range(0,1000) を 10000 回実行した平均の timeit は、リストの理解に 0.9 秒の時間を与え、reduce バージョンは 0.16 秒を与えます。したがって、フィルタリングを追加する前に、すでに 5 倍高速になっています。

于 2012-10-30T12:55:19.377 に答える
2

他の回答は、目的の要素を削除して新しいリストを作成する方法を示しています (これは、Python でこれを行う通常の方法です)。ただし、リストを適切に操作したい場合があります。リストを適切に操作する方法は次のとおりです。

while True:
    try:
        mylist.remove('')
    except ValueError:
        break

スライス割り当てとリスト内包表記でこれを行うことができると主張できると思いますが:

mylist[:] = [i for i in mylist if i != '']

また、メモリ使用量とジェネレーターの素晴らしさについて問題を提起した人もいます。

mylist[:] = (i for i in mylist if i != '')

も動作します。

于 2012-10-30T12:44:19.273 に答える
-1

''はFalseと同等です。0のケースを除外すると(0はFalseと同等であるため)、リスト内包表記を使用できます。

[x for x in a if x or x == 0]

または、空の文字列を厳密に除外したい場合:

[x for x in a if x != '']

これは最速の方法ではないかもしれません。

編集、他のソリューションと比較していくつかのベンチ結果を追加しました(自分自身を他のソリューションと比較するためではありませんが、どの方法が最速であるかについても興味がありました)

ragsagar>
6.81217217445
pistache>
1.0873541832
cerealy>
1.07090902328
Matt>
1.40736508369
Ashwini Chaudhary>
2.04662489891
Phil H (just the generator) >
0.935978889465
Phil H with list() >
3.58926296234

リストとして使用したtimeit()を使用して、スクリプトをすばやく作成しまし[0,1,2,0,3,4,'',5,8,0,'',4]た。複数のテストを実行しましたが、結果は変わりませんでした。

注:速度を基準として、ソリューションを最優先にしようとはしていません。OPが特に速度を要求しなかったことは知っていますが、私は興味があり、おそらく他の人が要求していました。

于 2012-10-30T12:34:53.403 に答える
-1
mylist = [1, 2, 3, '', 4]
newlist = []
for i in mylist:
    try:
        newlist.append(int(i))
    except ValueError:
        pass
avg = sum(newlist)/len(newlist)
于 2012-10-30T12:30:25.663 に答える