Python Dict 및 파일

Dict 해시 테이블

Python의 효율적인 키/값 해시 테이블 구조를 'dict'라고 합니다. 사전의 내용은 중괄호 { } 안에 일련의 키:값 쌍으로 작성할 수 있습니다. 예를 들어 dict = {key1:value1, key2:value2, ... }와 같이 입력합니다. 'empty dict'(빈 dict) 는 빈 중괄호 한 쌍 {}일 뿐입니다.

사전에서 값을 검색하거나 설정할 때는 대괄호를 사용합니다. 예: dict['foo']는 'foo' 키에서 값을 조회합니다. 문자열, 숫자, 튜플은 키로 작동하며 어떤 유형이든 값이 될 수 있습니다. 다른 유형은 키로 올바르게 작동할 수도 있고, 그렇지 않을 수도 있습니다 (문자열과 튜플은 변경 불가능하므로 깔끔하게 작동). dict에 없는 값을 검색하면 KeyError가 발생합니다. 'in'을 사용하세요. 키가 dict에 있는지 확인하거나, 값을 반환하는 dict.get(key)를 사용하거나 키가 없는 경우 None을 사용합니다 (또는 get(key, not-found)를 사용하여 찾을 수 없는 경우 반환할 값을 지정할 수 있습니다).

  ## Can build up a dict by starting with the empty dict {}
  ## and storing key/value pairs into the dict like this:
  ## dict[key] = value-for-that-key
  dict = {}
  dict['a'] = 'alpha'
  dict['g'] = 'gamma'
  dict['o'] = 'omega'

  print(dict) ## {'a': 'alpha', 'o': 'omega', 'g': 'gamma'}

  print(dict['a'])     ## Simple lookup, returns 'alpha'
  dict['a'] = 6       ## Put new key/value into dict
  'a' in dict         ## True
  ## print(dict['z'])                  ## Throws KeyError
  if 'z' in dict: print(dict['z'])     ## Avoid KeyError
  print(dict.get('z'))  ## None (instead of KeyError)

'a' 키가 포함된 dict 'o' 'g'

사전의 for 루프는 기본적으로 키를 반복합니다. 키는 임의의 순서로 표시됩니다. dict.keys() 및 dict.values() 메서드는 키 또는 값의 목록을 명시적으로 반환합니다. (키, 값) 튜플 목록을 반환하는 items()도 있습니다. 이는 사전의 모든 키-값 데이터를 검사하는 가장 효율적인 방법입니다. 이러한 목록은 모두 saved() 함수에 전달될 수 있습니다.

  ## By default, iterating over a dict iterates over its keys.
  ## Note that the keys are in a random order.
  for key in dict:
    print(key)
  ## prints a g o

  ## Exactly the same as above
  for key in dict.keys():
    print(key)

  ## Get the .keys() list:
  print(dict.keys())  ## dict_keys(['a', 'o', 'g'])

  ## Likewise, there's a .values() list of values
  print(dict.values())  ## dict_values(['alpha', 'omega', 'gamma'])

  ## Common case -- loop over the keys in sorted order,
  ## accessing each key/value
  for key in sorted(dict.keys()):
    print(key, dict[key])

  ## .items() is the dict expressed as (key, value) tuples
  print(dict.items())  ##  dict_items([('a', 'alpha'), ('o', 'omega'), ('g', 'gamma')])

  ## This loop syntax accesses the whole dict by looping
  ## over the .items() tuple list, accessing one (key, value)
  ## pair on each iteration.
  for k, v in dict.items(): print(k, '>', v)
  ## a > alpha    o > omega     g > gamma

전략 참고사항: 성능의 관점에서 볼 때 사전은 가장 유용한 도구 중 하나이며 데이터를 쉽게 구성하는 방법으로 사용해야 합니다. 예를 들어 각 줄이 IP 주소로 시작되는 로그 파일을 읽고, IP 주소를 키로 사용하고 그 값이 값으로 나타나는 줄 목록을 사용하여 데이터를 dict에 저장할 수 있습니다. 전체 파일을 읽고 나면 모든 IP 주소를 조회하고 행 목록을 즉시 볼 수 있습니다. 사전은 분산된 데이터를 일관성 있는 데이터로 만듭니다.

음성기록 서식

% 연산자는 사전의 값을 이름으로 문자열로 쉽게 대체할 수 있도록 편리하게 작동합니다.

  h = {}
  h['word'] = 'garfield'
  h['count'] = 42
  s = 'I want %(count)d copies of %(word)s' % h  # %d for int, %s for string
  # 'I want 42 copies of garfield'

  # You can also use str.format().
  s = 'I want {count:d} copies of {word}'.format(h)

삭제

'del' 연산자는 삭제를 수행합니다. 가장 단순한 경우에는 변수가 정의되지 않은 것처럼 변수의 정의를 삭제할 수 있습니다. Del을 목록 요소나 슬라이스에서 사용하여 목록의 해당 부분을 삭제하고 사전에서 항목을 삭제할 수도 있습니다.

  var = 6
  del var  # var no more!

  list = ['a', 'b', 'c', 'd']
  del list[0]     ## Delete first element
  del list[-2:]   ## Delete last two elements
  print(list)      ## ['b']

  dict = {'a':1, 'b':2, 'c':3}
  del dict['b']   ## Delete 'b' entry
  print(dict)      ## {'a':1, 'c':3}

파일

open() 함수가 열리고 일반적인 방식으로 파일을 읽거나 쓰는 데 사용할 수 있는 파일 핸들을 반환합니다. 코드 f = open('name', 'r')은 파일을 변수 f로 열고 읽기 작업을 준비하고 완료되면 f.close()를 사용합니다. 'r' 대신 'w'를 사용하세요. 로, 'a'는 '추가'를 선택합니다. 표준 for-loop는 텍스트 파일에 대해 작동하며, 파일의 행을 반복합니다 (바이너리 파일이 아닌 텍스트 파일에서만 작동함). for 루프 기법을 사용하면 텍스트 파일의 모든 라인을 간단하고 효율적으로 볼 수 있습니다.

  # Echo the contents of a text file
  f = open('foo.txt', 'rt', encoding='utf-8')
  for line in f:   ## iterates over the lines of the file
    print(line, end='')    ## end='' so print does not add an end-of-line char
                           ## since 'line' already includes the end-of-line.
  f.close()

한 번에 한 줄씩 읽으면 모든 파일이 한 번에 메모리에 들어가지 않아도 되는 좋은 품질을 얻을 수 있습니다. 10GB의 메모리를 사용하지 않고 10GB 파일의 모든 줄을 보려는 경우에 유용합니다. f.readlines() 메서드는 전체 파일을 메모리로 읽고 그 내용을 줄의 목록으로 반환합니다. f.read() 메서드는 전체 파일을 단일 문자열로 읽으므로 텍스트를 모두 한 번에 간편하게 처리할 수 있습니다(예: 나중에 살펴볼 정규 표현식을 사용하는 경우).

쓰기의 경우, f.write(string) 메서드는 열린 출력 파일에 데이터를 쓰는 가장 쉬운 방법입니다. 또는 '인쇄'를 사용할 수도 있습니다. 'print(string, file=f)'와 같은 열린 파일로 교체해야 합니다.

파일 유니코드

유니코드로 인코딩된 파일을 읽고 쓰려면 `'t'` 모드를 사용하고 인코딩을 명시적으로 지정하세요.

with open('foo.txt', 'rt', encoding='utf-8') as f:
  for line in f:
    # here line is a *unicode* string

with open('write_test', encoding='utf-8', mode='wt') as f:
    f.write('\u20ACunicode\u20AC\n') #  €unicode€
    # AKA print('\u20ACunicode\u20AC', file=f)  ## which auto-adds end='\n'

점진적 개발 연습

Python 프로그램을 빌드할 때는 전체를 한 번에 작성하지 마세요. 대신 첫 번째 마일스톤(예: "첫 번째 단계는 단어 목록을 추출하는 것입니다." 해당 마일스톤에 도달하는 코드를 작성하고 해당 지점의 데이터 구조를 출력한 다음 sys.exit(0)를 실행하여 프로그램이 완료되지 않은 부분을 지나치지 않도록 합니다. 마일스톤 코드가 작동하면 다음 마일스톤 코드를 작성할 수 있습니다. 한 상태에서 변수 출력을 볼 수 있으면 다음 상태로 가기 위해 변수를 변환하는 방법을 생각하는 데 도움이 될 수 있습니다. Python은 이 패턴에서 매우 빠르기 때문에 약간의 변경을 하고 프로그램을 실행하여 어떻게 작동하는지 확인할 수 있습니다. 그 빠른 처리 시간을 활용하여 간단한 단계만으로 프로그램을 빌드하세요.

연습문제: wordcount.py

모든 기본 Python 자료(문자열, 목록, 사전, 튜플, 파일)를 조합한 상태에서 기본 실습의 요약 wordcount.py 연습을 진행해 보세요.