2012-03-01 4 views
4

이름 (성, 이름)의 .txt 파일을 한 줄에 하나씩 읽는 프로그램을 만들고 특정 이름이 반복되는 횟수를 보여주는 사전을 만듭니다.파이썬에서는 키의 빈도에 따라 사전의 값을 어떻게 편집합니까?

나는 지금까지 추적 코드를 얻었지만 정확하게 이름을 반복하는 횟수를 계산할 수 없습니다. 문제는 내 변수 "value"가 키 값 쌍의 실제 값과 일치하지 않는다는 것입니다. 어떻게 해결할 수 있습니까? 당신은 같은 것을 원하는처럼

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

(!) 참고 : 변수 이름 * 파일 *와 같은 이름의 * DICT * 그림자 내장 명령. 다른 변수 이름을 사용해보십시오. –

답변

2

그것은 같습니다 또한

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

을 나는 것 강하게 당신이 namesdict이 아닌 다른 이름을 선택하는 것이 좋습니다. 이유는 보통 str, int 또는 list이라는 Python 변수를 생성하고 싶지 않기 때문에 dict이 표준 Python 사전 유형의 이름입니다.

collections.defaultdict과 같이 더 간결한 다른 솔루션이 있습니다.

+1

"dict '을 변수 이름으로 사용하지 마십시오."라는 우수한 점. 그 두 번째 주석. – Aurora

+2

'.has_key()'메소드보다 사전에 키의 존재를 테스트하기 위해'in' 연산자를 사용하는 것이 좋습니다 (메소드 조회가 없기 때문에).하지만 개념은 동일하게 유지됩니다. – jathanism

+4

권장 순서는 * dict.get *으로 시작한 다음 * collections.Counter *로 시작하고 * collections.defaultdict *에 대한 가능한 언급 만 시작합니다. * get * 권장 사항은 필수적입니다. 왜냐하면 새로운 유형을 배우기 위해 분기하기 전에 모든 근본적인 방식을 알아야하기 때문입니다. * Counter *는 사용법이 더 쉽습니다 (즉, 팩토리 함수 또는 인수가없는 * int *가 0을 반환한다는 지식이 필요하지 않음). 그리고이 유스 케이스에 맞게 특별히 설계되었으므로 * defaultdict *보다 우선합니다. –

2

당신이 가진 경우 블록을 대체 할 수

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

다른 방법으로, 대신 DICT의 collections.Counter를 사용할 수 있습니다. 즉, 계산 코드에 단순화 단지 :

c[firstname] += 1 

C카운터 인스턴스입니다.

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 : 다른 답변에 표시된 if 문보다 defaultdict가 우선합니다. –

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를 사용하여이 모든 것을 한 줄로 만들 수 있습니다 :''print counter (line.rstrip(). partition (',') [1] for f)'' –

관련 문제