JSON और CSV
csv मॉड्यूल से कोट्स वाली टेबल पढ़ना और लिखना, newline="" की आवश्यकता, json से संरचित डेटा रखना, और कौन से प्रकार रास्ते में बदल जाते हैं।
- 1समस्या
- 2समझें
- 3उदाहरण
- 4अनुमान
- 5स्वयं करें
- 6चुनौती
वह समस्या जिसे हम हल कर रहे हैं
अध्याय तेईस से हम .split(",") के साथ फ़ाइलों को विभाजित करते आ रहे हैं, और यह काम करता था। अब एक ऐसी फ़ाइल पर विचार करें जहाँ किसी फ़ील्ड के अंदर ही एक अल्पविराम (comma) है:
name,note,price
pen,blue ink,15.0
bag,"large, sturdy",850.0with open("items.csv", "r", encoding="utf-8") as fh:
for line in fh:
print(line.strip().split(","))['name', 'note', 'price']
['pen', 'blue ink', '15.0']
['bag', '"large', ' sturdy"', '850.0']अंतिम पंक्ति तीन के बजाय चार फ़ील्ड के साथ निकली, और उद्धरण चिह्न डेटा का हिस्सा बन गए।
उद्धरण चिह्न कोई गलती नहीं है — यह सीएसवी का नियम है, और यह ठीक इसी स्थिति के लिए मौजूद है। गलती हमारे पढ़ने के तरीके में है।
यह काम पहले से ही किया जा चुका है:
import csv
with open("items.csv", "r", encoding="utf-8", newline="") as fh:
for row in csv.reader(fh):
print(row)['name', 'note', 'price']
['pen', 'blue ink', '15.0']
['bag', 'large, sturdy', '850.0']यह अध्याय दो प्रारूपों के बारे में है — तालिकाओं के लिए CSV, संरचना के लिए JSON — और दोनों के लिए मॉड्यूल पायथन के साथ आते हैं।
इस मिशन के अंत तक आप सीखेंगे
csv.readerऔरcsv.DictReaderसे पढ़ना, औरcsv.writerसे लिखना- यह समझना कि
newline=""क्यों लिखा जाता है json.dumps/loadsऔरjson.dump/loadके बीच अंतर बताना- यह जानना कि कौन से पायथन प्रकार JSON से वापस आते हैं और कौन से नहीं
- CSV और JSON के बीच सही चुनाव करना
JSONDecodeErrorको पढ़ना और समस्या खोजना
पूर्वापेक्षाएँ: एक्सेप्शन्स — टूटी हुई स्थिति को संभालना.
CSV पढ़ना
csv.DictReader पहली पंक्ति को हेडर मानता है और प्रत्येक पंक्ति को एक डिक्शनरी बनाता है:
import csv
with open("items.csv", "r", encoding="utf-8", newline="") as fh:
for row in csv.DictReader(fh):
print(row["name"], "-", row["price"], type(row["price"]))pen - 15.0 <class 'str'>
bag - 850.0 <class 'str'>दो बातें:
पहुँच नाम द्वारा होती है, इसलिए कॉलमों का क्रम बदलने से कोड नहीं टूटता। DictReader लगभग हमेशा बेहतर विकल्प होता है।
लेकिन price अभी भी टेक्स्ट है। csv मॉड्यूल केवल फ़ील्ड्स को अलग करता है, उन्हें परिवर्तित नहीं करता।
CSV लिखना
डिक्शनरी की एक सूची के लिए, DictWriter:
import csv
rows = [
{"name": "pen", "price": 15.0},
{"name": "bag", "price": 850.0},
]
with open("out.csv", "w", encoding="utf-8", newline="") as fh:
writer = csv.DictWriter(fh, fieldnames=["name", "price"])
writer.writeheader()
writer.writerows(rows)name,price
pen,15.0
bag,850.0newline=""क्यों?csvमॉड्यूल स्वयं तय करता है कि पंक्ति का अंत क्या है।newline=""कुछ प्रणालियों पर हर पंक्ति के बाद खाली पंक्ति आने से रोकता है।
JSON — ऐसी संरचना जो एक तालिका में नहीं समा सकती
CSV एक तालिका है: पंक्तियाँ और कॉलम, सब कुछ समतल (flat)। लेकिन क्या होगा यदि किसी ऑर्डर में आइटमों की एक सूची हो, और प्रत्येक आइटम में टैग्स की एक सूची हो? एक तालिका उसे नहीं संभाल सकती।
import json
order = {"name": "pen", "price": 15.0, "tags": ["ink", "blue"], "stocked": True, "note": None}
print(json.dumps(order)){"name": "pen", "price": 15.0, "tags": ["ink", "blue"], "stocked": true, "note": null}json.dumps पायथन ऑब्जेक्ट को टेक्स्ट में बदलता है। ध्यान दें: True बन गया true और None बन गया null।
पठनीय बनाने के लिए indent=2:
import json
order = {"name": "pen", "tags": ["ink", "blue"]}
print(json.dumps(order, indent=2)){
"name": "pen",
"tags": [
"ink",
"blue"
]
}और इसे वापस लाना:
import json
text = '{"name": "pen", "price": 15.0, "stocked": true, "note": null}'
order = json.loads(text)
print(order)
print(type(order["price"]), type(order["stocked"]), order["note"] is None){'name': 'pen', 'price': 15.0, 'stocked': True, 'note': None}
<class 'float'> <class 'bool'> Trueयह CSV से सबसे बड़ा अंतर है। price एक संख्या के रूप में वापस आया और stocked True के रूप में। JSON प्रकारों (types) को साथ रखता है; CSV नहीं रखता।
चार नाम याद रखना आसान है: dumps/loads टेक्स्ट (strings) के साथ काम करते हैं, dump/load फ़ाइलों के साथ काम करते हैं।
JSON क्या वापस नहीं देता
प्रत्येक पायथन ऑब्जेक्ट JSON में नहीं जा सकता:
import json
data = {"pair": (1, 2), "numbers": {3, 4}}
print(json.dumps({"pair": data["pair"]}))
print(json.dumps(data)){"pair": [1, 2]}
TypeError: Object of type set is not JSON serializableएक टपल चुपचाप एक सूची बन जाता है। JSON में कोई टपल नहीं है।
एक सेट बिल्कुल नहीं जा सकता (TypeError)।
JSON कीज़ हमेशा टेक्स्ट होती हैं। संख्यात्मक कीज़ चुपचाप स्ट्रिंग बन जाती हैं: {1: "a"} बन जाता है {"1": "a"}।
सुरक्षित प्रकार: डिक्शनरी, लिस्ट, टेक्स्ट, संख्याएँ, True/False और None।
एक संपूर्ण उदाहरण
items.csv:
name,note,price,quantity
pen,blue ink,15.0,3
bag,"large, sturdy",850.0,1
ink,,120.0,2
clip,broken,,4main.py:
"""वस्तुओं की एक CSV पढ़ें, उसका योग करें, और परिणाम को JSON के रूप में लिखें।"""
import csv
import json
from pathlib import Path
TAX_RATE = 0.15
def read_items(path):
"""उपयोग योग्य पंक्तियों और समस्याओं को लौटाता है। csv कोट्स को संभालता है।"""
items = []
problems = []
with open(path, "r", encoding="utf-8", newline="") as fh:
for number, row in enumerate(csv.DictReader(fh), start=2):
try:
items.append({
"name": row["name"],
"note": row["note"],
"amount": round(
float(row["price"]) * int(row["quantity"]) * (1 + TAX_RATE), 2),
})
except ValueError as err:
problems.append(f"line {number}: {err}")
return items, problems
def main():
items, problems = read_items(Path("items.csv"))
summary = {
"items": items,
"total": round(sum(item["amount"] for item in items), 2),
"skipped": problems,
}
Path("summary.json").write_text(
json.dumps(summary, indent=2) + "
", encoding="utf-8")
print(Path("summary.json").read_text(encoding="utf-8"), end="")
if __name__ == "__main__":
main(){
"items": [
{
"name": "pen",
"note": "blue ink",
"amount": 51.75
},
{
"name": "bag",
"note": "large, sturdy",
"amount": 977.5
},
{
"name": "ink",
"note": "",
"amount": 276.0
}
],
"total": 1305.25,
"skipped": [
"line 5: could not convert string to float: ''"
]
}जब यह टूटता है
मेरी CSV की प्रत्येक पंक्ति के बाद एक खाली पंक्ति आ रही है newline="" पास नहीं किया गया था। लिखते समय इसे पास करें।
TypeError: Object of type set is not JSON serializable एक सेट, डेट या आपका अपना ऑब्जेक्ट पास किया गया था। इसे पहले लिस्ट या टेक्स्ट में बदलें।
मेरे टपल लिस्ट के रूप में वापस आए यह सामान्य है — JSON में टपल नहीं होता। यदि आवश्यक हो तो बाद में tuple(...) कॉल करें।
चरण 4 / 6 — अनुमान
अपनी समझ की जाँच करें
A three-column file, split by hand. How many fields come out?
# items.csv
# name,note,price
# pen,blue ink,15.0
# bag,"large, sturdy",850.0
with open("items.csv", "r", encoding="utf-8") as fh:
for line in fh:
print(len(line.strip().split(",")))- A3 3 4
- B3 3 3
- C3 3 5
- DA `ValueError`
DictReader read the row. What happens on the second line?
# items.csv
# name,price
# pen,15
import csv
with open("items.csv", "r", encoding="utf-8", newline="") as fh:
row = next(csv.DictReader(fh))
print(row)
print(row["price"] + 1)- AThe dictionary prints, then a `TypeError` — `price` is still text
- BThe dictionary prints, then `16`
- CThe dictionary prints, then `151`
- DA `KeyError`
json.dumps is given a Python dictionary. What is printed?
import json
print(json.dumps({"name": "pen", "stocked": True, "note": None}))- A{"name": "pen", "stocked": true, "note": null}
- B{"name": "pen", "stocked": True, "note": None}
- C{'name': 'pen', 'stocked': True, 'note': None}
- D{"name": "pen", "stocked": true}
उत्तर देने के लिए अकाउंट आवश्यक है
अपने उत्तर जाँचने के लिए साइन इन करें
प्रश्न ऊपर दिए गए हैं, और मन में उत्तर सोचना ही मुख्य कार्य है। सही उत्तर, व्याख्या और तीन-स्तरीय संकेत देखने के लिए साइन इन करें।
आपकी बारी
title,author,pages,year कॉलम और कम से कम छह पंक्तियों के साथ एक books.csv बनाएं। कम से कम एक शीर्षक में अल्पविराम लगाएं (ताकि उसे कोट्स में रखना पड़े), एक पंक्ति में pages खाली छोड़ें, और दूसरी में pages की जगह अक्षर रखें।
फिर library.py लिखें जो:
DictReaderके साथ फ़ाइल को पढ़ता है- लेखक द्वारा एक सारांश बनाता है
- पूरी चीज़ को
indent=2के साथlibrary.jsonमें लिखता है - उस फ़ाइल को वापस पढ़ता है और पुष्टि करता है कि कुल योग अपरिवर्तित है।
Step 6 of 6
चुनौती — the chapter quiz
सरल से कठिन — दस प्रश्न, अंतिम वाले जानबूझकर चुनौतीपूर्ण बनाए गए हैं।
Sign in to take the quiz