Python Dict 및 파일

Dict 해시 테이블

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

사전에서 값을 조회하거나 설정할 때는 대괄호를 사용합니다. 예를 들어 dict['foo']는 'foo' 키 아래의 값을 조회합니다. 문자열, 숫자, 튜플은 키로 작동하며 모든 유형이 값이 될 수 있습니다. 다른 유형은 키로 올바르게 작동할 수도 있고 작동하지 않을 수도 있습니다(문자열과 튜플은 불변이므로 제대로 작동함). 사전에 없는 값을 조회하면 KeyError가 발생합니다. 'in'을 사용하여 키가 사전에 있는지 확인하거나 dict.get(key)를 사용하여 값을 반환하거나 키가 없으면 None을 반환합니다. get(key, not-found)를 사용하면 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', 'o', 'g'인 사전

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

  ## 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 주소를 키로, IP 주소가 나타나는 줄 목록을 값으로 사용하여 데이터를 사전에 저장할 수 있습니다. 전체 파일을 읽고 나면 모든 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)'와 같이 열린 파일과 함께 'print'를 사용할 수 있습니다.

파일 유니코드

유니코드로 인코딩된 파일을 읽고 쓰려면 `'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 연습을 시도해 보세요.