전형적인 json 형태의 표현이에요.
key-value
형식의 pair
입니다.
{
"firstName": "Jane",
"lastName": "Doe",
"hobbies": ["running", "sky diving", "singing"],
"age": 35,
"children": [
{
"firstName": "Alice",
"age": 6
},
{
"firstName": "Bob",
"age": 8
}
]
}
어찌 보면 전형적인 파이썬
dictionary
형태라는 것도 인식 할 수 있어요.
built-in package
-> JSON🎇내장 패키지로 json을 사용할 수 있어요.
import json
JSON
형태로 변형 시키는걸 serialization
이라고 하고 그 반대는 deserialization
이라고 하겠조?
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str | string |
int, long, float | number |
True | true |
False | false |
None | null |
메모리에 아래와 저장된 것을 파일로 저장 시켜 볼까요?
data = {
"president": {
"name": "Zaphod Beeblebrox",
"species": "Betelgeusian"
}
}
context manager를 이용해서 data_file.json
이름의 파일을 만들어 볼거에요.
json.dump()
이녀석을 사용해서 첫 번째 인자에 python python dictionary
객체를 넣고 2번째에는 작성할 파일의 변수를 넣어주면 되요.
즉
serialization
해야 할data
를 첫번째 위치인수로 지정하고bytes
로 작성되어야 할 것을 2번째 위치 인수로 지정합니다.
with open('data_file.json', 'w') as wirete_file:
json.dump(data, write_file)
만약 2번째 인수가 json.dumps(data)
에 지정하지 않으면 disk에 저장하는게 아니에요~
print('첫 번째 아래 표준형입니다.')
print(json.dumps(data))
print('두 번째 아래 indent=5 넣었을 때')
print(json.dumps(data, indent=5))
print('세 번째 아래 sort_keys=True 했을때')
print(json.dumps(data, indent=5, sort_keys=True))
print('네 번째 아래 separators=(\'!\', \'@\') 넣었어요')
print(json.dumps(data, indent=5, sort_keys=True, separators=('!', '@')))
output
첫 번째 줄은 보기가 어렵지만
3 번째부터는 적당히 인덱트가 넣어져서 일기 매우 좋아요~ 가독성굿~!
첫 번째 아래 표준형입니다.
{"president": {"name": "Zaphod Beeblebrox", "species": "Betelgeusian", "age": 22}}
두 번째 아래 indent=5 넣었을 때
{
"president": {
"name": "Zaphod Beeblebrox",
"species": "Betelgeusian",
"age": 22
}
}
세 번째 아래 sort_keys=True 했을때
{
"president": {
"age": 22,
"name": "Zaphod Beeblebrox",
"species": "Betelgeusian"
}
}
네 번째 아래 separators=('!', '@') 넣었어요
{
"president"@{
"age"@22!
"name"@"Zaphod Beeblebrox"!
"species"@"Betelgeusian"
}
}
Case1에서 dump()
, dumps()
를 통해서 Python 데이터를 JSON 데이터로 변환시키는걸 봤조?
이제는 이와 대응되는 'load()`, 'loads()'메서드를 통해서 JSON --> Python 데이터로 변화시키는걸 볼게요.
JSON | Python |
---|---|
object | dict |
array | list |
string | str |
number | (int) int |
number | (real) float |
true | True |
false | False |
null | None |
기본적으로 서로
encoding(serialization), JSON화하기
<-->>decoding(serialization), python 객체화하기
대응된다고 했는데, 실제로는 그렇지도 않습니다.
한번 보시조.
요약하면 처음 파이썬 튜플
이 인코딩 -> 디코딩
을 거쳐 당연히 튜플
로 나올줄 알았는데
리스트
로 나타난걸 확인 할 수 있어요.
이점에 유의하면 되요.
print('인코딩 디코딩 서로 정확히 대응될까요?')
blackjack_hand = (8, "Q")
print(type(blackjack_hand))
encoded_hand = json.dumps(blackjack_hand)
print('인코딩한거',encoded_hand, '데이터유형',type(encoded_hand))
decoded_hand = json.loads(encoded_hand)
print('디코딩한거',decoded_hand, '데이터유형',type(decoded_hand))
print(blackjack_hand == decoded_hand, '이론상 서로 같아야 해요.')
output
인코딩 디코딩 서로 정확히 대응될까요?
<class 'tuple'>
인코딩한거 [8, "Q"] 데이터유형 <class 'str'>
디코딩한거 [8, 'Q'] 데이터유형 <class 'list'>
False 이론상 서로 같아야 해요.
<class 'tuple'> 파이썬 데이터형
<class 'list'> 인코딩하고 나서 파이썬 데이터 유형
True 결국 튜플로 해줘야 동일함
Case1과는 정반대로 disk에 저장된 데이터를 메모리에 올려서 데이터 마사지를 하고 싶다면 어떻게 할까요?
우선 with open()
구문을 read 모드를 이요해서 열여줘야겠조?
with open("data_file.json", "r") as read_file:
data = json.load(read_file)
json_string = """
{
"researcher": {
"name": "Ford Prefect",
"species": "Betelgeusian",
"relatives": [
{
"name": "Zaphod Beeblebrox",
"species": "Betelgeusian"
}
]
}
}
"""
data = json.loads(json_string)
이번에는 requests 모듈을 사용할게요(없으면 pip install requests
해주세요)
import json
import requests
response = requests.get("https://jsonplaceholder.typicode.com/todos")
todos = json.loads(response.text)
print()
print()
print('실사례!')
print(todos == response.json())
print(type(todos))
print(todos[:10])
output
실사례!
True
<class 'list'>
[{'userId': 1, 'id': 1, 'title': 'delectus aut autem', 'completed': False}, {'userId': 1, 'id': 2, 'title': 'quis ut nam facilis et officia qui', 'completed': False}, {'userId': 1, 'id': 3, 'title': 'fugiat veniam minus', 'completed': False}, {'userId': 1, 'id': 4, 'title': 'et porro tempora', 'completed': True}, {'userId': 1, 'id': 5, 'title': 'laboriosam mollitia et enim quasi adipisci quia provident illum', 'completed': False}, {'userId': 1, 'id': 6, 'title': 'qui ullam ratione quibusdam voluptatem quia omnis', 'completed': False}, {'userId': 1, 'id': 7, 'title': 'illo expedita consequatur quia in', 'completed': False}, {'userId': 1, 'id': 8, 'title': 'quo adipisci enim quam ut ab', 'completed': True}, {'userId': 1, 'id': 9, 'title': 'molestiae perspiciatis ipsa', 'completed': False}, {'userId': 1, 'id': 10, 'title': 'illo est ratione doloremque quia maiores aut', 'completed': True}]
아래 코드를 한번 쭉쭉 이해한다? 그럼 JSON을 파이썬 객체와 같이 술술술 작성하는 경지에 이른거에요!
저는 아니지만~ 예~~~!!!
# Map of userId to number of complete TODOs for that user
todos_by_user = {}
# Increment complete TODOs count for each user.
for todo in todos:
if todo["completed"]:
try:
# Increment the existing user's count.
todos_by_user[todo["userId"]] += 1
except KeyError:
# This user has not been seen. Set their count to 1.
todos_by_user[todo["userId"]] = 1
# Create a sorted list of (userId, num_complete) pairs.
top_users = sorted(todos_by_user.items(),
key=lambda x: x[1], reverse=True)
# Get the maximum number of complete TODOs.
max_complete = top_users[0][1]
# Create a list of all users who have completed
# the maximum number of TODOs.
users = []
for user, num_complete in top_users:
if num_complete < max_complete:
break
users.append(str(user))
max_users = " and ".join(users)
s = "s" if len(users) > 1 else ""
print(f"user{s} {max_users} completed {max_complete} TODOs")
# users 5 and 10 completed 12 TODOs
아래 코드까지 이해했다?! 그럼 당신은 정말이지~~!!!
# Define a function to filter out completed TODOs
# of users with max completed TODOS.
def keep(todo):
is_complete = todo["completed"]
has_max_count = str(todo["userId"]) in users
return is_complete and has_max_count
# Write filtered TODOs to file.
with open("filtered_data_file.json", "w") as data_file:
filtered_todos = list(filter(keep, todos))
json.dump(filtered_todos, data_file, indent=2)