次のようなファイルを取ろうとしています。 ``none 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'`というエラーが出続けます。辞書のキーはリストにできないことは知っていますが、私はキーではなく値をリストにしたいのです。どこかで間違えているのではないかと思っています。
他の回答にもあるように、エラーの原因は k = list[0:j]
で、キーがリストに変換されていることです。ひとつの方法として、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:`) を使ってファイルを開けば、問題なく動作するはずです。
k(これはリストです)を
d`のキーとして使おうとしています。リストはミュータブルなので、dictのキーとしては使えません。
また、この行のせいで、辞書の中のリストを決して初期化していません。
if k not in d == False:
となっているはずです。
if k not in d == True:
実際には、次のようになります。
if k not in d:
k = list[0:j]という行で別のリストからのスライスを使って作成されているため、
TypeErrorが発生しています。 これはおそらく
k = ' '.join(list[0:j])` のようにすべきで、そうすれば代わりに文字列ができます。
これに加えて、Jesse'さんの回答にもあるように、あなたのif
文は間違っています。if k not in d
またはif not k in d
(私は後者の方が好きです)と読むべきです。
また、for
ループの中でd = {}
としているので、繰り返しのたびに辞書をクリアしています。
また、list
や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
ロジックを置き換えるものです。