2012-03-23 2 views
4

파이썬 작업에 약간의 문제가 있습니다. CMD를 통해 실행되는 코드를 작성해야합니다. 나는 사용자가 언급 한 파일을 열어 그 안에 들어있는 알파벳 문자의 수를 세는 것이 필요하다.파이썬 정규식과 CMD

지금까지 CDM을 실행하고 파일을 열 수있는 상태입니다. 정규 표현식을 뒤죽박죽으로 사용했지만 개별 문자를 계산하는 방법을 알아낼 수 없습니다. 어떤 아이디어? 미안해, 내가 잘못 설명했다면.

import sys 
import re 


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

이 숙제인가? 그렇다면 태그로 지정해야합니다. –

+1

아니, '신인을위한 파이썬'을 사용하고 작업을 수행하고 있습니다. 그러나 나는 미래의 참고를 위해 이것을 명심 할 것이다. 덕분에 – Unknown

+1

+1 좋은 질문 :-) –

답변

1

정규식에서 멀리 떨어져있을 것입니다. 그들은 느리고 추한 것입니다. 대신 전체 파일을 문자열로 읽고 내장 문자열 메서드 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' (파이썬 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 

결과를 보려면 : 이것은 파이썬 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

이것은 Counter 클래스를 @ KevinCoffey보다 훨씬 유용하게 사용합니다. –