2012-03-01 19 views
4

名前(姓、名)の.txtファイルを1行に1つずつ読み込み、特定のファーストネームが繰り返される回数を示す辞書を作成しています。Pythonでは、キーの頻度に基づいて辞書の値をどのように編集しますか?

私はこれまでのコードを手に入れましたが、名前の繰り返し回数を正確にカウントできないようです。問題は、私の変数「値」がキー値のペアの実際の値に対応していないことです。どうすれば修正できますか?

file = open('names.txt') 

dict = {} 
value = 1 

for line in file: 
    listOfNames = line.split(",") 
    firstName = listOfNames[1] 

    if dict.has_key(firstName): 
     value += 1 
    else: 
     dict[firstName] = value 

file.close() 
+4

追記:変数名*ファイル*と同じ名前の*辞書*影の組み込みコマンド。異なる変数名の使用を検討してください。 –

答えて

2

それはあなたが何かしたいのようになります。

また
if dict.has_key(firstName): 
    dict[firstName] += 1 
else: 
    dict[firstName] = 1 

を、私は強くは、あなたがそのようなnamesとして、dict以外の名前を選択することをお勧めします。その理由は、普通のPythonの辞書型の名前であるの場合です。strint、またはlistというPython変数を作成したくないのと同じように、dictは標準のPython辞書型の名前です。

さらに簡潔になるcollections.defaultdictを使用するなどの他の解決策があります。

+1

「変数名としてdictを使用しないでください」の優れた点。私はそのコメントの秒です。 – Aurora

+2

これは、より高度に最適化された操作(メソッドルックアップなし)がコンセプトは同じなので、 '.has_key()'メソッドと比較して 'in'演算子を辞書のキーの存在をテストするために使用することが推奨されています。 – jathanism

+4

推奨の順番は* dict.get *で始まり、* collections.Counter *で始まり、* collections.defaultdict *の可能な記述だけです。新しいタイプを学ぶためにブランチアウトする前に、すべての基礎辞書のメソッドを知っておく必要があるため、* get *の推奨事項は必須です。 * Counter *は使いやすく(つまり、ファクトリ関数や引数がない* int *がゼロを返す知識を必要としない)、このユースケース専用に設計されているため、* defaultdict *よりも優先されます。 –

2

あなたがしている場合、ブロックを置き換えることができます。

dict[firstname] = dict.get(firstname, 0) + 1 

また、あなたの代わりに辞書のcollections.Counterを使用することができます。 Cカウンタインスタンス

c[firstname] += 1 

:それだけにカウントコードを簡素化します。

2

使用このようなdefaultdict

from collections import defaultdict 
d = defaultdict(int) 
for name in open('names.txt'): 
    _, first_name = name.split(",") 
    d[first_name] += 1 

あなたは空白と大文字をストリッピングすることにより、あなたの名前を正規化することもできます。

+0

コレクションよりもカウンタが優先されます。このユースケースのdefaultdict –

+0

+1:defaultdictは、他の答えに示されたif文よりも優先されます。 –

2

@Auroraが言及しているように、Counterはこれに最適です。

>>> names = ['foo bar', 'foo baz', 'foo car', 'doo bar', 'doo baz', 'boo paz'] 
>>> from collections import Counter 
>>> Counter(name.split()[1] for name in names) 
Counter({'baz': 2, 'bar': 2, 'paz': 1, 'car': 1}) 
2
with open('names.txt') as f: 
    firstNames = [line.split(',')[0] for line in f] 

print collections.Counter(firstNames) 
+0

補題:最終的に姓に行く場合、 '.read()。splitlines()'を実行しない限り、改行文字を '.strip()'する必要があるかもしれないことに注意してください。 – ninjagecko

+0

カウンタのコンストラクタを使用してこの名前のリストを自動的にループする場合は+1。また、genexpを使ってすべての行を1つの行にまとめることもできます:f)行のprint counter(line.rstrip()。partition( '、')[1] –

関連する問題