2012-03-23 9 views
4

私はPythonの作品のいくつかの問題を抱えています。 CMDを実行するコードを書く必要があります。ユーザーが記述したファイルを開き、それに含まれる各アルファベット文字の数を数える必要があります。Pythonの正規表現とCMD

これまでのところ、CDMを実行してファイルを開くことができます。私は正規表現を使いこなしましたが、個々の文字を数える方法はまだ分かりません。何か案は?私がこれをひどく説明したら申し訳ありません。

import sys 
import re 


filename = raw_input() 
count = 0 
datafile=open(filename, 'r') 
+1

はこの宿題ですか?もしそうなら、そのようにタグ付けされるべきです。 –

+1

いいえ、私は 'ルーキーのためのpython'を使用してタスクを通過します。私は将来の参照のためにそれを念頭に置いておきます。ありがとう – Unknown

+1

+1良い質問:-) –

答えて

1

私はregexesから離れています。彼らは遅くて醜いでしょう。代わりに、ファイル全体を文字列に読み込み、組み込みの文字列メソッドcountを使用して文字を数えます。あなたのためにそれを一緒に入れて

filename = raw_input() 
datafile=open(filename, 'r') 
data = datafile.read() 
datafile.close() # Don't forget to close the file! 
counts = {} # make sure counts is an empty dictionary 
data = data.lower() # convert data to lowercase 
for k in range(97, 123): # letters a to z are ASCII codes 97 to 122 
    character = chr(k) # get the ASCII character from the number 
    counts[character] = data.count(character) 

を次に、あなたはすべてのカウントを含む辞書countsを持っています。たとえば、counts['a']はファイル内にaの数を示します。または、カウントの全リストについては、counts.items()を実行してください。

+1

大きなファイルの場合、カウント機能を使用するとパフォーマンスが低下します。データセット全体は、カウントされている各文字ごとに読み取られます。 –

+1

まあ、いつものように、実際に行うことはパフォーマンスを測定することです。そして少なくとも100MBまでのファイルでは、上記のコードは 'collections'(私のマシン上では、Python 2.7.2で)を使うときよりも少なくとも15倍速いです。これは、スクリプト全体、またはループのいずれかに当てはまります。 – Mike

3

カウンタータイプはアイテム数をカウントするのに便利です。あなたは正規表現を使用したい場合は、次のようにあなたが行うことができ、

results = [(key, value) for key, value in counts.items() if key.isalpha()] 
print results 
+0

@TimLesherファイルのサイズはどのように再生されますか? –

+1

列挙を使用したいとは思わない:列挙は、(k、v)のシーケンスではなく、(n、k)のシーケンスを与える。 –

+0

私は単一の読み込みとループを提案しようとしていました。私はそれが新しい答えとしてより明確になることに気付きました。 –

1

pattern = re.compile('[^a-zA-Z]+') # pattern for everything but letters 
only_letters = pattern.sub(text, '') # delete everything else 
count = len(only_letters) # total number of letters 

をカウントするための

import collections 
counts = collections.Counter() 
for line in datafile: 
    # remove the EOL and iterate over each character 
    #if you desire the counts to be case insensitive, replace line.rstrip() with line.rstrip().lower() 
    for c in line.rstrip(): 
     # Missing items default to 0, so there is no special code for new characters 
     counts[c] += 1 

は結果を表示するには:それは、Python 2.7で追加されました異なる文字の数は、すでにアドバイスされているカウンターを使用してください。

1

正規表現は、文字列内で複雑なパターンを検索する場合に便利です。シンプルな(アルファベットの文字は1つだけ) "パターン"を数えたいと思うので(正規表現とは対照的に)、正規表現はここで選択するツールではありません。

私が試していることを正しく理解している場合、これを解決する最も透過的な方法は、すべての行を繰り返し、その行のすべての文字を繰り返し処理し、その文字がアルファベットの場合は、エントリ。コードでは:このループは、ファイルを介して実行している

filename=raw_input() 
found = {} 

with open(filename) as file: 
    for line in file: 
     for character in line: 
      if character in "abcdefghijklmnopqrstuvxyz": 
      # Checking `in (explicit string)` is not quick, but transparent. 
      # You can use something like `character.isalpha()` if you want it to 
      # automatically depend on your locale. 
       found[character] = found.get(character, 0)+1 
       # If there is no dictionary entry for character yet, assume default 0 
       # If you need e.g. small and capital letters counted together, 
       # "Normalize" them to one particular type, for example using 
       # found[character.upper()] = found.get(character, 0)+1 

後、辞書foundは、各文字の出現箇所の数が含まれています。

+0

lower()と組み合わされた文字列関数isalpha()は、 "abcdefghijklmnopqrstuvxyz"と入力するより簡単です –

2

ファイルを一度読まれるのに十分小さい場合、それは確かに非常に簡単です:

from collections import Counter 

filename = raw_input() 
with open(filename) as f: 
    data = f.read() 
counter = Counter(data.lower()) 

print('\n'.join(str((ch, counter[ch])) for ch in counter if ch.isalpha())) 
+1

これは、@ KevinCoffey'sよりCounterクラスの方がはるかに優れています。 –