2012-12-02 11 views
32

私はこのPythonの:TypeError例外:非ハッシュの種類:「リスト」

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

、出力はこの

{AAA: ['111', '112'], AAB: ['111'], AAC: [123], ...} 
のように見えるように辞書を使用するように見えるファイルを取るしようとしています非ハッシュタイプ: 'list' の

これは私が

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を得続けるを試してみたものです。私は辞書のキーはリストにすることはできませんが、私はキーではなくリストに自分の価値を見出そうとしていることを知っています。私はどこかでミスを犯したのだろうかと思っています。

私の最後の質問で私を助けてくれてありがとう皆に感謝します。

答えて

20

他の回答に示されているように、エラーはk = list[0:j]であり、キーはリストに変換されています。あなたは、Python 3.xを使用している場合、あなたはそれが正常に動作を取得するために微調整を行う必要がありますことを

# 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']} 

注:あなたが試みることができることの一つは、split機能を利用するようにコードを再加工です。 rbでファイルを開く場合は、line = line.split(b'x')を使用する必要があります(バイトを適切なタイプの文字列に分割していることを確認してください)。with open('filename.txt', 'rU') as f:(またはさらにwith open('filename.txt', 'r') as f:)を使用してファイルを開くこともできます。正常に動作するはずです。

+0

これを試してみましたが、TypeErrorが発生しました:type strは、バッファーAPIをライン上でサポートしていません "line = line.split( 'x')" – Keenan

+0

@ user1871081ああ、Python 3.xを使用していますか?私はそれで動作するアップデートを投稿します。 – RocketDonkey

+1

@ user1871081素晴らしい、すべてのことで幸運。 – RocketDonkey

10

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

また、あなたがあるため、この行のため、辞書にリストを初期化することはありませんしている:

でなければなりません
if k not in d == False: 

if k not in d: 
:実際にする必要があります

if k not in d == True: 

+0

。 – Keenan

0

kがリストであるため、TypeErrorが起きています他のリストのスライスをk = list[0:j]としてください。これはおそらくk = ' '.join(list[0:j])のようなものになるはずなので、代わりに文字列があります。これに加えて

if k not in dまたはif not k in dを(私は後者を好む)読んでくださいジェシーの回答で述べたように、あなたのifの文が正しくありません。

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ロジックを置き換えます。

+0

優先権はあなたの完全な権利ですが、 'not k in d'は初心者を' 'd' 'の中に混乱させる可能性がありますが、' k in d'はあいまいさがありません –

+0

私はそれが ' 「not in」と表示されるのは、[演算子](http://docs.python.org/2/reference/expressions.html#not-in)です。 –

+0

ええ、私の好みは他の言語を最初に習得したことでしょう。これは、封じ込めテストのようなものに対しては、演算子を持たないので、 '!a.contains(b)'のようなことをします。 'not in'はもっとpythonであるかもしれませんが、私はブール式でinverseを使うよりも、2つの単語演算子のコンセプトがもっと混乱していると思っています。 –

2

が例外になる理由は、k = list[0:j]kをリストの「スライス」(通常は短いリスト)に設定しているためです。あなたが必要とするのは、k = list[0]のように書かれたリストの最初の項目だけを取得することです。 v = list[j + 1:]の場合は、readline.split(" ")への呼び出しから返されたリストの3番目の要素については、v = list[2]にする必要があります。

私はいくつかの他のコードに気が付きました。ループ内で毎回dを初期化したくないというのは、それぞれの行が読み取られるときにd = {}と表示されることです。もう1つは、組み込み型と同じ名前を変数に付けるのは良い考えではありません。なぜなら、必要なときに組み込み関数にアクセスできなくなり、その名前に使用されている他の人が混乱してしまうからです標準的なもの。そのため、変数listの名前を変更して、このような問題を避ける必要があります。

ここで私はまた、キーがそれを行うには、暗黙的な方法がさらに簡単ある辞書—に既に存在するかどうかをチェックし、あなたが持っていたif文の表現を単純化しますが、この、あなたのことで、これらの変更での作業バージョンです道は今のところ十分です。

d = {} 
file = open("filename.txt", "r") 
readline = file.readline().rstrip() 
while readline: 
    lst = readline.split(" ") # split into list like ['AAA', 'x', '111'] 
    k = lst[0] # first item 
    v = lst[2] # third item 
    if k not in d: # new key? 
     d[k] = [] # initialize value 
    d[k].append(v) 
    readline = file.readline().rstrip() 

print 'd:', d 

出力:でも、それはまだ同じエラーを与える変更に

d: {'AAA': ['111', '112'], 'AAC': ['123'], 'AAB': ['111']} 
-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)