Đây có phải là những gì bạn đang theo đuổi?
>>> orig = {
.. 'place_nm': [
.. {'lu_stat_id': 1, 'lu_use_desig_id': 1, 'place_nm': u'National Monument'},
.. {'lu_stat_id': 1, 'lu_use_desig_id': 1, 'place_nm': u'Joe\'s Bar'},
.. {'lu_stat_id': 1, 'lu_use_desig_id': 1, 'place_nm': u'Pike\'s Peak'},
.. {'lu_stat_id': 1, 'lu_use_desig_id': 1, 'place_nm': u'Niagara Falls'},
.. {'lu_stat_id': 1, 'lu_use_desig_id': 1, 'place_nm': u'Dulles Airport'},
.. {'lu_stat_id': 1, 'lu_use_desig_id': 1, 'place_nm': u'Bay Bridge'},
.. {'lu_stat_id': 1, 'lu_use_desig_id': 1, 'place_nm': u'Bagram Airfield'},
.. {'lu_stat_id': 1, 'lu_use_desig_id': 1, 'place_nm': u'McDonals'}
.. ]
.. }
>>>
>>> new = {}
>>> for k,v in orig.items[]:
.. new["table"] = k
.. new["inserts"] = []
.. if v:
.. for d in v:
.. flds = list[d.keys[]]
.. new["inserts"].append[{
.. "fields": flds,
.. "values": [d[f] for f in flds]
.. }]
...
>>> import pprint
>>> pprint.pprint[new]
{'inserts': [{'fields': ['lu_stat_id', 'lu_use_desig_id', 'place_nm'],
'values': [1, 1, 'National Monument']},
{'fields': ['lu_stat_id', 'lu_use_desig_id', 'place_nm'],
'values': [1, 1, "Joe's Bar"]},
{'fields': ['lu_stat_id', 'lu_use_desig_id', 'place_nm'],
'values': [1, 1, "Pike's Peak"]},
{'fields': ['lu_stat_id', 'lu_use_desig_id', 'place_nm'],
'values': [1, 1, 'Niagara Falls']},
{'fields': ['lu_stat_id', 'lu_use_desig_id', 'place_nm'],
'values': [1, 1, 'Dulles Airport']},
{'fields': ['lu_stat_id', 'lu_use_desig_id', 'place_nm'],
'values': [1, 1, 'Bay Bridge']},
{'fields': ['lu_stat_id', 'lu_use_desig_id', 'place_nm'],
'values': [1, 1, 'Bagram Airfield']},
{'fields': ['lu_stat_id', 'lu_use_desig_id', 'place_nm'],
'values': [1, 1, 'McDonals']}],
'table': 'place_nm'}
>>>
Tuy nhiên, sử dụng những cách đơn giản này làm cho mã rất ít khái quát hóa. Nếu bạn muốn phân tích giá trị của
key3_value = json["key2"]["key3"]
1, thì bạn cần thêm một dòng mới vào mã của mìnhkey4_value = json["key2"]["key4"]
Thật kém hiệu quả. Điều làm cho vấn đề tồi tệ hơn là chỉ có thể viết loại mã này khi bạn biết chính xác đường dẫn đến khóa hoặc tệ hơn, đường dẫn đến một khóa nhất định có thể không tĩnh và thay đổi thường xuyên. Trong trường hợp đó, bạn cần viết mã mỗi khi định dạng của json thay đổi. Có rất nhiều API chúng ta có thể sử dụng xung quanh mình. Họ trả về nhiều json ở nhiều định dạng khác nhau. Thật vậy, bạn cần biết ít nhất từng cấu trúc cây json. Nhưng, nếu bạn có thể viết mã được khái quát hóa tốt để phân tích các json khác nhau, thì nó rất hữu ích.
Vì mục đích đó, tôi đã cố gắng viết mã có khả năng phân tích cú pháp qua cây json theo cách đệ quy/động và cập nhật các cặp khóa-giá trị tại một điểm nhất định trong cây json.
2. Vấn đề
Thực ra nếu mục đích chỉ để phân tích cú pháp [chứ không cập nhật] thì đã không đến nỗi khó hiểu. Chỉ cần viết mã đơn giản như thế này
def recursively_parse_json[input_json, target_key]:
if type[input_json] is dict and input_json:
if key == target_key:
print input_json[key]
for key in input_json:
recursively_parse_json[input_json[key], target_key]
elif type[input_json] is list and input_json:
for entity in input_json:
recursively_parse_json[entity, target_key]
Được rồi, mã này trả về giá trị của
key3_value = json["key2"]["key3"]
2. [Nhưng hãy chắc chắn rằng key3_value = json["key2"]["key3"]
2 phải là khóa duy nhất trong cây json. ]Sau đó, giả sử bạn muốn cập nhật giá trị của
key3_value = json["key2"]["key3"]
2, thì nên thêm loại dòng nào?Trong ví dụ rất đơn giản, bạn có thể thêm loại này . [Điều này khó viết mã đến mức bạn không thể viết mã này nếu không biết có bao nhiêu khóa tồn tại trong đường dẫn đến
key3_value = json["key2"]["key3"]
2. Nhưng ở đây tôi muốn bạn hiểu rằng để cập nhật giá trị tại một điểm nhất định trong cây json, bạn cần biết ít nhất đường dẫn [phím đến mục tiêu]. ]________số 8
Để triển khai đoạn mã này, lúc đó tôi đang nghĩ theo cách của Java/C nên tôi đã nghĩ theo cách sau.
Đầu tiên, bạn cần biết đường dẫn đến
key3_value = json["key2"]["key3"]
2. Do đó, cần lưu trữ các khóa trong danh sách trong khi tìm hiểu đầu vào json. Sau đó, bạn sẽ nhận được loại danh sách này. key3_value = json["key2"]["key3"]
7. Bây giờ bạn có thể sử dụng danh sách này để chỉ định vị trí của key3_value = json["key2"]["key3"]
2 cây json. [Xin lỗi vì tuyên bố khó hiểu, nhưng tôi muốn làm rõ. nó đã sai. Trong trăn 2. 7 [3 cũng vậy?], trên thực tế, bạn không cần kiểu xử lý json này để cập nhật giá trị tại một điểm nhất định trong cây json. Khi ở trong "vòng lặp for" lồng nhau, bạn có thể dễ dàng cập nhật giá trị. Tôi sẽ giải thích điều này sau. Nhưng dù sao đi nữa, ở đây tôi muốn bạn biết rằng tôi nghĩ rằng tôi cần danh sách lưu trữ khóa [đường dẫn] đến
key3_value = json["key2"]["key3"]
2 trong khi tìm hiểu cây json để cập nhật giá trị đúng cách. ]Vì vậy, tôi đã sửa đổi mã ở trên để lưu trữ các khóa [đường dẫn] vào danh sách trong khi phân tích cú pháp json động và đệ quy cho đến khi đạt đến
key3_value = json["key2"]["key3"]
2key3_value = json["key2"]["key3"]
4Tại thời điểm này, tôi gặp phải vấn đề phạm vi. Sau khi chạy đoạn mã trên, danh sách chứa các khóa mà tôi không mong đợi
3. Phạm vi biến đổi. Trăn 2. 7 so với Java/C
[Khi tôi đang nghĩ theo cách của Java/C], những gì tôi mong đợi là như thế này.
Tại vị trí mũi tên màu đỏ chỉ, danh sách đường dẫn sẽ giống như
key3_value = json["key2"]["key3"]
51. Ở đây nó vẫn chưa gây nhầm lẫn. [Vì vấn đề văn chương, tôi xin dùng số liệu để giải thích. Tôi nghĩ không cần phải nói, nhưng mỗi chiếc lá đều có giá trị. ]]
Bây giờ, bạn đã chuyển sang chi nhánh tiếp theo, ở đây những gì tôi mong đợi là
key3_value = json["key2"]["key3"]
52. Nhưng giá trị thực tế là ____153. Tại sao điều này xảy ra?Trong nút
key3_value = json["key2"]["key3"]
54, quy trình truy cập vào từng nút con trong "vòng lặp for". Theo hiểu biết của tôi, tôi nghĩ rằng mỗi quy trình A và B nằm trong vòng lặp riêng và có phạm vi biến riêng. Trong Java và C, phạm vi biến trong vòng lặp for hoạt động theo cách đó. Vì ngôn ngữ lập trình đầu tiên của tôi là C, tôi bị kẹt ý tưởng nên không thể hiểu tại sao danh sách các khóa được lưu trữ mà lẽ ra không có ở đóSau một thời gian, tôi tìm thấy một chủ đề trong StackOverflow thảo luận về khối/phạm vi trong các vòng lặp trong Python. https. // stackoverflow. com/câu hỏi/3611760/phạm vi-trong-python-cho-vòng lặp
Nói tóm lại, theo luồng, một khối/phạm vi cục bộ được tạo trong mỗi vòng lặp trong Java/C nhưng nó không có trong Python. [Tôi muốn tìm tài liệu đề cập đến phạm vi bao phủ trong vòng lặp for. ] Đọc qua các nguồn khác, tôi nghĩ rằng vấn đề phạm vi này là nguyên nhân có thể nhất gây ra hành vi lạ. Sau đó, câu hỏi tiếp theo là làm cách nào để xác định phạm vi cục bộ trong mỗi vòng lặp? . ]
Cuối cùng, tôi tìm thấy một tài liệu nói
Phạm vi và thời gian tồn tại của biến
Biến được định nghĩa bên trong một hàm là cục bộ của hàm đó. Nó có thể truy cập từ điểm mà nó được xác định cho đến khi kết thúc chức năng và tồn tại miễn là chức năng đang thực thi.
http. // python-textbok. đọcthedocs. io/en/1. 0/Biến_và_Phạm vi. html
Được rồi, tôi hiểu rồi. Tôi đã sửa đổi mã ở trên và nhận được như sau
key3_value = json["key2"]["key3"]
9Tôi đã di chuyển dòng, nơi các khóa được lưu vào
key3_value = json["key2"]["key3"]
55, đến đầu hàm thay vì bên trong vòng lặp for. Bây giờ, nó trả về danh sách mong đợi key3_value = json["key2"]["key3"]
56 khi nó tìm thấy key3_value = json["key2"]["key3"]
2 trong khi phân tích cú pháp cây json theo cách đệ quy và linh hoạtBây giờ bạn đã có danh sách chứa các khóa dưới dạng đường dẫn đến một khóa nhất định trong cây json. Đã đến lúc bắt đầu viết mã cập nhật giá trị trong một json lồng nhau sâu chưa? . Trên thực tế, hóa ra là hoàn toàn không cần thiết phải lưu trữ các khóa dưới dạng đường dẫn để chỉ định vị trí trong cây json.
Tất cả những gì bạn phải làm chỉ là cập nhật giá trị của
key3_value = json["key2"]["key3"]
2 ngay khi bạn tìm thấy nó trong khi phân tích cú pháp đệ quy/động một json. key4_value = json["key2"]["key4"]
4Thành thật mà nói, tôi vẫn không chắc tại sao nó hoạt động.
Phân tích cú pháp qua cây json và tại vị trí mũi tên đỏ chỉ, nó sẽ tìm thấy
key3_value = json["key2"]["key3"]
2 và cập nhật giá trị của nó. Tôi hiểu cách nó tìm khóa và cập nhật giá trị. Đây chỉ là hoạt động json bình thường. Nhưng điều tôi không hiểu là tại sao bản cập nhật lại ảnh hưởng đến key4_value = json["key2"]["key4"]
0 toàn cầu thay vì địa phương. Điều này có liên quan đến điều đó trong Python "vòng lặp for" không có phạm vi cục bộ không?Dù sao, mặc dù vấn đề phạm vi này khiến tôi bối rối, nhưng nó cũng rất thú vị đối với tôi. Tôi không ngờ rằng có sự khác biệt lớn như vậy trong khái niệm phạm vi giữa các ngôn ngữ lập trình bởi vì nó rất cơ bản