144

次のようなファイルを取得しようとしています。

AAA x 111
AAB x 111
AAA x 112
AAC x 123
...

辞書を使用して、出力が次のようになるようにします

{AAA: ['111', '112'], AAB: ['111'], AAC: [123], ...}

これは私が試したものです

file = open("filename.txt", "r") 
readline = file.readline().rstrip()
while readline!= "":
    list = []
    list = readline.split(" ")
    j = list.index("x")
    k = list[0:j]
    v = list[j + 1:]
    d = {}
    if k not in d == False:
        d[k] = []
    d[k].append(v)
    readline = file.readline().rstrip()

私は取得し続けTypeError: unhashable type: 'list'ます。辞書のキーをリストにすることはできませんが、値をキーではなくリストにしようとしています。どこかで間違えたのではないかと思います。

4

7 に答える 7

72

他の回答で示されているように、エラーはk = list[0:j]、キーがリストに変換されるために発生します。試すことができることの1つは、split関数を利用するためにコードを作り直すことです。

# Using with ensures that the file is properly closed when you're done
with open('filename.txt', 'rb') as f:
  d = {}
  # Here we use readlines() to split the file into a list where each element is a line
  for line in f.readlines():
    # Now we split the file on `x`, since the part before the x will be
    # the key and the part after the value
    line = line.split('x')
    # Take the line parts and strip out the spaces, assigning them to the variables
    # Once you get a bit more comfortable, this works as well:
    # key, value = [x.strip() for x in line] 
    key = line[0].strip()
    value = line[1].strip()
    # Now we check if the dictionary contains the key; if so, append the new value,
    # and if not, make a new list that contains the current value
    # (For future reference, this is a great place for a defaultdict :)
    if key in d:
      d[key].append(value)
    else:
      d[key] = [value]

print d
# {'AAA': ['111', '112'], 'AAC': ['123'], 'AAB': ['111']}

Python 3.xを使用している場合は、正しく機能させるために微調整を行う必要があることに注意してください。でファイルを開く場合はrb、を使用する必要がありますline = line.split(b'x')(これにより、適切なタイプの文字列でバイトが分割されていることを確認できます)。with open('filename.txt', 'rU') as f:(または)を使用してファイルを開くこともでき、with open('filename.txt', 'r') as f:正常に動作するはずです。

于 2012-12-03T00:01:40.850 に答える
27

kのキーとして (リスト)を使用しようとしていますd。リストは変更可能であり、dict キーとして使用することはできません。

また、次の行があるため、辞書内のリストを初期化することはありません。

if k not in d == False:

次のようになります。

if k not in d == True:

実際には次のようになります。

if k not in d:
于 2012-12-02T23:52:14.453 に答える
6

unhashable type: 'list'例外が発生する理由は、k = list[0:j]セットがリストの「スライス」になるためです。kこれは、論理的に別の、多くの場合短いリストです。必要なのは、リストの最初の項目だけを取得することですk = list[0]。への呼び出しから返されるリストの 3 番目の要素についてもv = list[j + 1:]同じです。v = list[2]readline.split(" ")

このコードには他にも考えられる問題がいくつかあることに気付きました。そのうちのいくつかを取り上げます。大きな問題は、ループで読み取られる行ごとに (再) 初期化dしたくないことです。d = {}もう 1 つの理由は、変数に組み込み型と同じ名前を付けることは、必要なときにそれらの 1 つにアクセスできなくなるため、一般的には良い考えではありません。これらの標準項目の 1 つを指定する名前。そのため、そのlistような問題を回避するために、変数変数の名前を別の名前に変更する必要があります。

これらの変更を加えた作業バージョンを次に示します。またif、キーが既に辞書にあるかどうかを確認するために使用したステートメント式を置き換え、辞書のsetdefault()メソッドを使用して同じことをもう少し簡潔に行います。

d = {}
with open("nameerror.txt", "r") as file:
    line = file.readline().rstrip()
    while line:
        lst = line.split() # Split into sequence like ['AAA', 'x', '111'].
        k, _, v = lst[:3]  # Get first and third items.
        d.setdefault(k, []).append(v)
        line = file.readline().rstrip()

print('d: {}'.format(d))

出力:

d: {'AAA': ['111', '112'], 'AAC': ['123'], 'AAB': ['111']}
于 2012-12-03T02:22:20.700 に答える
0

これは、行を持つ別のリストのスライスを使用して作成されてTypeErrorいるため、リストであるため発生しています。これはおそらく のようなものになるはずなので、代わりに文字列があります。kk = list[0:j]k = ' '.join(list[0:j])

これに加えて、ifJesseの回答で指摘されているように、あなたの声明は正しくありませんif k not in d.or if not k in d(私は後者を好みます)。

ループd = {}内にあるため、反復ごとに辞書もクリアしています。for

ビルトインをマスクするため、listorを変数名として使用しないでください。file

コードを書き直す方法は次のとおりです。

d = {}
with open("filename.txt", "r") as input_file:
    for line in input_file:
        fields = line.split()
        j = fields.index("x")
        k = " ".join(fields[:j])
        d.setdefault(k, []).append(" ".join(fields[j+1:]))

上記のメソッドは、コードのロジックをdict.setdefault()置き換えます。if k not in d

于 2012-12-02T23:55:46.887 に答える
-1
    python 3.2

    with open("d://test.txt") as f:
              k=(((i.split("\n"))[0].rstrip()).split() for i in f.readlines())
              d={}
              for i,_,v in k:
                      d.setdefault(i,[]).append(v)
于 2012-12-03T14:59:51.117 に答える