60 — 검색 — JSON에서 찾기
목록은 기록들의 모음입니다 — name과 tags가 든 딕셔너리. 검색 반복은
키워드를 물어보고 목록을 훑으며 이름이 맞는 기록을 골라냅니다. 이
가이드는 로컬 파일이나 HTTP 서버에서 목록을 불러오고 .lower()로
대소문자 구분 없이 글을 맞춥니다.
단계
기록 하나는
name과tags목록을 담습니다. 목록 전체는 그런 딕셔너리들의 모음이고catalog.json으로 저장됩니다:
실행해 보기 →[ {"name": "Red Apple", "tags": ["fruit", "sweet"]}, {"name": "Red Rose", "tags": ["flower", "garden"]}, {"name": "Green Tea", "tags": ["drink", "warm"]}, {"name": "Blueberry", "tags": ["fruit", "blue"]} ]프로그램 옆 파일에서 목록을 불러오거나, 파일이 없으면 로컬 서버에서 불러옵니다.
os.path.exists가 길을 고르고, 서버 부분은 55의urlopen줄입니다.json읽기와loads모두 같은 모양을 돌려줍니다 — 딕셔너리들의 목록:
실행해 보기 →import os 파일 사용 최신 from json import loads from urllib.request import urlopen if os.path.exists("catalog.json"): 상품들 = json읽기("catalog.json") else: url = "http://localhost:8000/catalog.json" 상품들 = loads(urlopen(url).read().decode("utf-8"))"Red" in "Red Apple"은 대소문자를 구분해서 소문자 검색이 놓칩니다..lower()이 문자열을 소문자로 복사하고, 양쪽에 붙이면 대소문자 구분 없는 매칭이 됩니다. 태그는 목록이라word.lower() in 상품["tags"]이 태그 목록 전체를 확인합니다 — 문자열과 목록에 쓰는 같은in연산자.Red Apple이 두 번 출력됩니다:
실행해 보기 →name = "Red Apple" word = "red" if word.lower() in name.lower(): 말해 name 상품 = {"name": "Red Apple", "tags": ["fruit", "sweet"]} if "sweet" in 상품["tags"]: 말해 상품["name"]found카운터가 "없음"을 침묵 대신 진짜 답으로 바꿉니다:
실행해 보기 →found = 0 for 상품 in 상품들: if "red" in 상품["name"].lower(): 말해 f"{상품['name']}: {', '.join(상품['tags'])}" found = found + 1 if found == 0: 말해 "없음"프로그램 전체입니다.
catalog.json옆에search.ko.nme으로 저장합니다:
실행해 보기 →# search.ko.nme — JSON 목록에서 찾기. # 실행: nme 실행 search.ko # search, list, quit 중 하나를 입력하세요. import os 파일 사용 최신 from json import loads from urllib.request import urlopen # 로컬 파일이나 로컬 서버에서 목록을 불러옵니다. if os.path.exists("catalog.json"): 상품들 = json읽기("catalog.json") else: url = "http://localhost:8000/catalog.json" 상품들 = loads(urlopen(url).read().decode("utf-8")) 말해 f"목록: {len(상품들)}개" while True: 말해 "명령: search, list, quit" 물어봐 명령, "? " if 명령 == "search": 물어봐 단어, "검색어? " found = 0 for 상품 in 상품들: # 양쪽을 소문자로 바꾸면 Red가 red를 찾습니다. name = 상품["name"].lower() if 단어.lower() in name or 단어.lower() in 상품["tags"]: 말해 f"{상품['name']}: {', '.join(상품['tags'])}" found = found + 1 if found == 0: 말해 "없음" elif 명령 == "list": for 상품 in 상품들: 말해 상품["name"] elif 명령 == "quit": 말해 "안녕!" break else: 말해 "알 수 없는 명령"검색은 이름과 태그를 모두 확인하므로
red는 이름으로Red Apple과Red Rose를 찾고,blue는 태그를 통해Blueberry를 찾습니다.파이프로 명령을 넣어 실행합니다.
search가red를 찾고,list가 모든 이름을 출력하며,quit이 반복을 끝냅니다:printf 'search\nred\nlist\nquit\n' | nme 실행 search.ko목록: 4개 명령: search, list, quit ? 검색어? Red Apple: fruit, sweet Red Rose: flower, garden 명령: search, list, quit ? Red Apple Red Rose Green Tea Blueberry 명령: search, list, quit ? 안녕!맞는 게 없는 키워드는
없음을 출력합니다. 서버 경로를 쓰려면 폴더에서python3 -m http.server 8000을 시작하고catalog.json이름을 바꾼 뒤 실행하세요 — 같은 프로그램이 HTTP로 똑같은 목록을 가져옵니다.
직접 해보기
이름 검사를 빼고 단어.lower()를 각 상품의 태그 목록에만 맞춰 보세요.
또는 반복 뒤에 f"{found}개 찾음"을 출력해 보세요.
배운 것
- 목록은
name과tags가 든 딕셔너리들의 모음입니다. os.path.exists가json읽기와loads(urlopen(...))사이를 고릅니다.- 양쪽
.lower()이in매칭을 대소문자 구분 없이 만듭니다. in은 문자열(name)과 목록(tags) 모두에 쓸 수 있습니다.found카운터가 빈 반복과 "없음"을 구분하게 해 줍니다.