2016-04-24 19 views
2

私はPythonで複数の辞書を降順でソートしようとしています。Pythonで複数のdictを値で並べ替える

highs = [] 
file_a = open("/home/victor/Documents/Python-3.5.1/[email protected]") 
def func(): 
    for line in file_a: 
     from collections import OrderedDict 
     s = {} 
     (s['date'], s['open'], s['high'], s['low'], s['close'], s['volume'], s['openinterest'], s['totalVolume'], s['totalOpenInterest']) = line.split(',') 
    newlist = sorted(s.items(), key=lambda s: float(s[2]), reverse = True) 

func() 
file_a.close() 

はしかし、私はそれを実行するたびに私はこのエラーを取得:

File "/home/victor/Documents/first project.py", line 8, in <lambda> 
newlist = sorted(s.items(), key=lambda s: float(s[2]), reverse = True) 
IndexError: tuple index out of range 

私は、Pythonに非常に新しいです。どんな助けもありがとう。

+2

'items()'は、2つの要素を含む 'tuple'オブジェクトを提供します。このような 'tuple 'の最高インデックスは' 2 'ではなく' 1 'です。 – TigerhawkT3

+0

"high"という値に基づいてテキストファイル内の行をどのようにソートすることができますか? –

+0

's'は、' 'date''、' 'open''、' 'high''のような文字列キーを持つ辞書ですが、' 'key''に数値2のキーを使用しようとしていますあなたの 'sorted()'呼び出しに渡された関数です。おそらく 'float(s ['high'])'が必要です。 – martineau

答えて

2

あなたのコードにある問題の1つは、ファイル全体を繰り返し繰り返して、sという名前の辞書オブジェクトを作成することですが、次のものを作成する前にそれらのそれぞれで何もしません。

エラーメッセージは、これらのディクショナリをすべて作成して無視した後、これを実行するリードループが完了した後でs.items()に値をソートしようとしているためです。つまり、sは(ファイルの最後の行から)作成された最後の辞書を保持したままになります。これは、各 - このリストの各項目では2つだけのものがあるので

[('volume', '300000'), ('high', '110'), ('low', '90') ('totalOpenInterest', '4.56'), 
('date', '01/01/16'), ('close', '101'), ('openinterest', '.99'), ('open', '100'), 
('totalVolume', '1000000')] 

:かかわらず、s.items()は、たとえば、のような何か含まれている場合があります(キー、値)ペアの辞書のリストのコピーであります、やや紛らわしい、またlambda機能のs引数と命名されました - 2は、これらの値のペアのそれぞれについて1のどのような最高の有効な指標よりも大きいのでので、あなたのコード内のfloat(s[2])IndexErrorを発生させます。

以下のコードは、正しく達成しようとしていると思います。最初にdataという名前の一時リストに作成されたs辞書をそれぞれ格納し、そのキー('high')によって参照される各値の1つでソートします。

def func(filename): 
    data = [] 
    with open(filename) as file_a: 
     for line in file_a: 
      line = line.rstrip() # remove newline at end 
      s = {} 
      (s['date'], s['open'], s['high'], s['low'], 
      s['close'], s['volume'], s['openinterest'], 
      s['totalVolume'], s['totalOpenInterest']) = line.split(',') 
      data.append(s) 

    return sorted(data, key=lambda s: float(s['high']), reverse=True) 

filename = "/home/victor/Documents/Python-3.5.1/[email protected]" 
sorted_dicts = func(filename) 
for d in sorted_dicts: 
    print(d) 
0

あなたは毎回辞書sを上書きするので、実際にファイルの最後の行以外を保存しているわけではありません。あなたは、リストでその辞書を格納する必要があります。

data = [] 
for line in file_a: 
    s = {} 
    (s['date'], s['open'], s['high'], s['low'], s['close'], s['volume'], s['openinterest'], s['totalVolume'], s['totalOpenInterest']) = line.split(',') 
    data.append(s) 

次にあなたがリストを並べ替えることができます。

newlist = sorted(data, key=lambda x: -float(x['high'])) 

(この例では、私はhighの負の値を使用しての代わりに使用していますことに注意してくださいreverse=True)。

OrderedDict回ごとにループを繰り返す必要があります。

1

三つの問題、両方このライン周り:

newlist = sorted(s.items(), key=lambda s: float(s[2]), reverse = True) 

まず、これはファイルのちょうど最後の行があるsを意味ループの外側にあります。前の行のデータはすべて破棄されています。第二に、すべてのデータを持っていても、新しい変数newlistに割り当てることは何も役に立ちません。あなたはおそらくhighsか何かに追加したいと思うでしょう。

しかし、表示されているエラーメッセージは、s.itemsがペア(2要素タプル)のリスト:[(key1, value1), (key2, value2), (key3, value3),...]を返すためです。単一のタプルsを指定すると、値でソートする場合は、それはs[1]です。キーはs[0]です。 s[2]は存在しません。これはタプルの3番目の要素ですが、1つもありません。

関連する問題