0

したがって、私の主な目標は単純です。単一のキーを使用したときに複数の値が返されるようにしたいのです。ただし、エラーが発生し、動作が混乱します。私は Python を初めて使用するので、この問題には単純な理由があると思います。

listオブジェクトのインデックスのみを含むオブジェクトのリストがあります。すなわち

1
2
3
4 
etc.. 

および各オブジェクトが属するグループを含むファイルが同じ順序でリストされています。ファイルは n 行の単一の値です (n はオブジェクトのリストの長さでもあります)。つまり、ファイルは次のようになります。

2
5
2
4
etc..

つまり、最初のオブジェクトはグループ 2 に属し、2 番目のオブジェクトはグループ 5 に属し、3 番目はグループ 2 に属し、4 番目はグループ 4 に属します。このファイルは入力ファイルによって異なります。次の2つの提案を試みました(見つけることができました)。

編集:私の最終目標:グループ番号をキーとして、グループ内のオブジェクトを値として持つ辞書を持つこと。

この StackOverflow questionは非常に似ているため、最初に助けを求めて調べたところ、次のコードになりました。

def createdDict(list, file): 

    f = open(file, 'r')
    d={}
    i=0 

    for line in f:
        groupIndex = int(line)
        if groupIndex in d:
            d[groupIndex].append(list[i])
        else:
            d[groupIndex] = list[i]
        i +=1
    print d
    f.close()

そして、このエラー:

AttributeError: 'Element' object has no attribute 'append'

d[groupIndex]は単なる辞書とそのキーでありgroupIndex、整数でもある必要があります。スクリプトの前半で作成したクラスのオブジェクトではありません。(なぜこのエラーが表示されるのですか?)

次に、この他の質問に出くわした後、コードを次のように修正しました。これは、タスクを達成するための別の方法だと思ったからです。私のコードは次のようになりました:

def createdDict(list, file): 

    f = open(file, 'r')
    d={}
    i=0 

    for line in f:
        groupIndex = int(line)
        if groupIndex in d:
            d.setdefault('groupIndex', []).append(list[i])
        else:
            d[groupIndex] = list[i]
        i +=1
    print d
    f.close()

このコード スニペットは、エラーまたは私が望むもので終わるのではなく、むしろ (私が信じている) グループ内の最後のオブジェクトです...したがってprint d、キーと、グループに配置された最後のオブジェクト (目的の代わりに) が得られます: そのグループ内のすべてのオブジェクト)、次に端末がランダムに吐き出し、groupIndex続いて 内のすべてのオブジェクトが吐き出されlistます。

私の質問: ここで何が欠けているのでしょうか? 私がリンクした質問への回答に人々が賛成票を投じたので、それらは正しい可能性が高く、私はそれらを間違って実装している可能性があります。両方の手順を修正する必要はありませんが、1 つのキーに複数の値を関連付けるという私の問題に対する最も効率的な答えです。このタスクを達成するための最もpythonicな方法は何でしょうか?

編集2:これがまったく役立つ場合、最初のメソッドがエラーを参照しているクラスもここにあります。このコードの一部をこのクラスの一部としてどのように定義したかはわかりません。私はまだそれを実際に開発していませんが、私はすべて答えを求めているので、これがエラーの特定に役立つ場合:

class Element(object):
    def __init__(self, globalIndex):
        self.globalIndex = globalIndex
    def GetGlobalIndex (self):
        return self.globalIndex

globalIndexオブジェクト (要素) の個別のインデックスです。現在の問題では、これらの要素のリスト (これは前述のリスト) を取得し、ファイルに基づいてそれらを小さなグループにグループ化しています (これも前述)。リストは本質的に整数のカウントアップです...それは私のコードをどのように台無しにしますか?

4

4 に答える 4

6

問題のベースは次の行にあります。

d[groupIndex] = list[i]

つまり、キーがディクショナリにない場合、そのキーの下に単一の値(Elementオブジェクト) を追加します。次にそのキーが表示されたときに、その単一の値に追加しようとします。ただし、単一の値に追加することはできません。追加するには、リストなどのコンテナー タイプが必要です。Python は魔法のようにElementオブジェクトをリストに変換しません!

解決策は簡単です。辞書の値をリストにしたい場合は、そうしてください。最初の項目を追加するときは、1 要素のリストを追加します。

d[groupIndex] = [list[i]]

または、元のリストの 1 項目のスライスを取得することもできます。これはすでにリストになります。

d[groupIndex] = list[i:i+1]

これで、ディクショナリの値は常にリストになり、2 番目以降の値をエラーなしでリストに追加できます。

ecatmurが指摘しているようにifd.setdefault(groupIndex, []).append(list[i]). キーが存在しない場合、値は空のリストと見なされ、常に新しいアイテムを追加するだけです。を使用することもできますcollections.defaultdict(list)

于 2012-07-09T19:40:40.997 に答える
2

使うだけ

d.setdefault(groupIndex, []).append(list[i])

これは にあるかどうかをチェックするgroupIndexのでd、その行は必要ありませんif groupIndex in d:

于 2012-07-09T19:37:13.803 に答える
2
from itertools import izip
from collections import defaultdict

dd = defaultdict(list)
with open('filename.txt') as fin:
    for idx, line in izip(my_list, fin):
        num = int(line)
        defaultdict[num].append(idx)

これによりdefaultdict、デフォルトのタイプのリストで が作成されるため、 を使用せずに追加できますsetdefault。次に、ファイルから対応する行と結合された の各要素を読み取りmy_list、その行を整数に変換してから、グループ ( で表されるnum) に対応するインデックスを追加します。

于 2012-07-09T19:40:49.033 に答える
1

最初の試行では、辞書項目に最初の要素を追加することは特殊なケースであり、辞書項目にはまだ値がないため、まだ追加できないことを正しく理解しているようです。

あなたの場合、それを list[i] に設定します。ただし、list[i] はリストではないため、後の反復で追加を実行することはできません。

私は次のようなことをします:

for line in f:
    groupIndex = int(line)
    try:
        blah = d[groupIndex] # to check if it exists
    except:
        d[groupIndex] = [] # if not, assign empty list

    d[groupIndex].append(list[i])
print d
f.close()
于 2012-07-09T19:42:12.383 に答える