לפעמים, תרצה עותק מלא של אובייקט, פעמים אחרות תרצה שהוא ישתמש בהפניות. ראה את ההבדלים בפעולה.
פייתון מציעה מספר גישות יעילות לניהול נתונים. הבנת מושגי העתקה רדודה ועמוקה היא חיונית כאשר עובדים עם מבני נתונים כמו רשימות מקוננות, מילונים או אובייקטים מותאמים אישית.
העתקה רדודה ועמוק מאפשרת לך ליצור העתקים של מבני נתונים, אך הם פועלים אחרת לגבי נתונים מקוננים.
שימוש ב-Shallow Copy
עותק רדוד עובד על ידי יצירת עותק של המבנה ברמה העליונה של האובייקט המקורי. המשמעות היא שאם האובייקט המקורי מכיל אובייקטים מקוננים, העותק יפנה לאותם אובייקטים מקוננים שהמקור עושה. במילים אחרות, יצירת עותק רדוד של אובייקט משכפלת את המבנה החיצוני ביותר שלו, לא כל אובייקט מקונן שהוא עשוי להכיל.
כדי לבצע עותק רדוד ב- Python, אתה יכול להשתמש במודול ההעתקה עותק() פונקציה או ה .עותק() שיטה על האובייקט.
שקול דוגמה של עבודה עם רשימה או מילון ב-Python.
import copy
main_list = [29, 49, ["Q", "R"]]
shallow_copy = copy.copy(main_list)# Modify the nested list
shallow_copy[2][0] = 99
main_list[2][1] = 100
print(f"The main list: {main_list}")
print(f"The shallow copy list: {shallow_copy}")
בקוד למעלה, ה main_list משתנה מחזיק רשימה המכילה מספרים שלמים ורשימה פנימית (אובייקט מקונן) המכילה אותיות. פונקציית ההעתקה יוצרת עותק של main_list שהקוד מאחסן במשתנה אחר, רדוד_עותק.
כל שינוי שתבצע ב- רדוד_עותק רשימה מקוננת תשפיע ישירות גם על זו של main_list ולהיפך. שינויים אלה מראים שהרשימה המקוננת או הפנימית של ה רדוד_עותק הוא רק התייחסות לזה של main_list, גורם לשינויים לחול ב main_list גַם.
בינתיים, כל שינוי שנעשה בפריטים החיצוניים (המספרים השלמים) בכל אחד מהם רדוד_עותק אוֹ main_list ישפיע רק על המקרה הזה. פריטים חיצוניים אלה הם ערכים עצמאיים בפני עצמם, לא רק אזכורים בלבד.
import copy
main_list = [29, 49, ["Q", "R"]]
shallow_copy = copy.copy(main_list)# Modify the outer items
shallow_copy[0] = "M"
main_list[1] = "N"
print(f"The main list: {main_list}")
print(f"The shallow copy list: {shallow_copy}")
הפלט מוכיח שהפריטים החיצוניים של שני הרשימה אינם תלויים זה בזה:
אותו רעיון חל בעבודה עם מילונים.
dict1 = {'ten': 10, 'twenty': 20, 'double':{'thirty': 30, 'sixty': 60}}
dict2 = dict1.copy()# Modify inner and outer elements
dict1['double']['thirty'] = 30.00
dict1['ten'] = 10.00
print(f"The main dictionary, {dict1}")
print(f"The shallow copy dictionary, {dict2}")
שינויים שבוצעו במילון המקנן של dict1 להשפיע על שניהם dict1 ו dict2. במקביל, שינויים בפריטים החיצוניים של dict1 להשפיע רק עליו.
שימוש ב-Deep Copy
במקום להתייחס לאובייקטים המקוננים של העותק המקורי, עותק עמוק יוצר עותק נפרד לחלוטין של האובייקט המקורי והאובייקטים המקוננים שלו. שינוי העותק העמוק לא ישפיע על האובייקט המקורי ולהיפך; הם באמת ערכים נפרדים.
כדי ליצור עותק עמוק ב- Python, השתמש ב- deepcopy() הפונקציה של מודול ההעתקה.
שקול דוגמה לעבודה עם רשימה.
import copy
main_list = [200, 300, ["I", "J"]]
deep_copy = copy.deepcopy(main_list)# Modify the inner and outer list
deep_copy[2][0] = "K"
main_list[0] = 500
print(f"The main list: {main_list}")
print(f"The deep copy list: {deep_copy}")
כאן, הקוד מבצע העתקה עמוקה של main_list, יצירת עותק עצמאי בשם deep_copy.
כאשר אתה משנה את הרשימה המקוננת או הפריטים החיצוניים ב- deep_copy, השינויים שלך אינם משפיעים על הרשימה המקורית, ולהיפך. זה מדגים שהרשימה המקוננת או הרכיבים החיצוניים אינם משותפים בין שני העותקים.
עבודה עם אובייקטים מותאמים אישית
אתה יכול ליצור אובייקט מותאם אישית על ידי הגדרת מחלקה Python ויצירת מופע של המחלקה.
הנה דוגמה ליצירת אובייקט פשוט מ-a סֵפֶר מעמד:
classBook:
def__init__(self, title, authors, price):
self.title = title
self.authors = authors
self.price = price
def__str__(self):
returnf"Book(title='{self.title}', author='{self.authors}', \
price='{self.price}')"
כעת, צור גם עותק רדוד וגם עותק עמוק של מופע של זה סֵפֶר כיתה באמצעות עותק מודול.
import copy
# Create a Book object
book1 = Book("How to MakeUseOf Shallow Copy", \
["Bobby Jack", "Princewill Inyang"], 1000)# Make a shallow copy
book2 = copy.copy(book1)# Modify the original object
book1.authors.append("Yuvraj Chandra")
book1.price = 50
# Check the objects
print(book1)
print(book2)
כפי שאתה יכול לראות, העותק הרדוד (ספר2) הוא אובייקט חדש, אך הוא מתייחס לאותו אובייקט פנימי (רשימת מחברים) כמו האובייקט המקורי (ספר 1). לפיכך, שינוי במחברי האובייקט המקורי משפיע על שני המקרים (ספר1 וספר2), בעוד ששינוי בפריט החיצוני (מחיר) משפיע רק על האובייקט המקורי (ספר 1).
מצד שני, יצירת עותק עמוק יוצרת עותק עצמאי של האובייקט המקורי, כולל עותקים של כל האובייקטים הכלולים בו.
# Create a Book object
book1 = Book("Why MakeUseOf Deep Copy?", \
["Bobby Jack", "Yuvraj Chandra"], 5000)# Make a deep copy
book2 = copy.deepcopy(book1)# Modify the original object
book1.authors.append("Princewill Inyang")
book1.price = 60
# Check the objects
print(book1)
print(book2)
במקרה זה, העותק העמוק (ספר2) הוא אובייקט עצמאי לחלוטין, ומשנה את האובייקט המקורי (ספר 1) אינו משפיע עליו.
שימושים עבור העתקה רדודה והעתקה עמוקה
זה חיוני להבין עותק עמוק ורדוד כדי שתוכל לבחור את הגישה המתאימה למניפולציה של נתונים. להלן כמה תרחישים שבהם כל שיטה ישימה:
- השתמש בעותק רדוד אם ברצונך לשכפל אובייקט מורכב מבלי ליצור מופעים חדשים של האובייקטים המקוננים שלו. גישה זו יעילה יותר בזיכרון ומהירה יותר מהעתקה עמוקה מכיוון שהיא אינה משכפלת אובייקטים מקוננים.
- השתמש בעותק רדוד כדי ליצור תמונת מצב של מצב אובייקט תוך שיתוף נתונים בסיסיים בין האובייקט המקורי לאובייקט שהועתק.
- השתמש בעותק עמוק אם ברצונך לשנות העתק של אובייקט מבלי להשפיע על המקור. זה יוצר עותקים עצמאיים של אובייקטים מקוננים, ומבטיח שכל שינוי בעותק אינו חל על המקור.
- העתקה עמוקה היא קריטית כאשר אתה צריך עותקים עצמאיים של מבני נתונים מקוננים, בעיקר כאשר מתמודדים עם היררכיות אובייקט רקורסיביות או מורכבות.
ביצועים ושיקולים
מאחר שהעותק רדוד אינו מייצר מופעים חדשים של אובייקטים מקוננים, הוא בדרך כלל פועל מהר יותר וצורך פחות זיכרון מאשר העתקה עמוקה. עם זאת, למקור ולעותק הרדוד עלולות להיות תופעות לוואי לא רצויות משינוי פריטים פנימיים משותפים.
במיוחד עבור מבני נתונים גדולים ומקוננים עמוקים, העתקה עמוקה, הליך רקורסיבי, יכול להיות איטי יותר ולהשתמש ביותר זיכרון. עם זאת, זה מבטיח עצמאות מוחלטת בין המקור לשכפול העמוק, מה שהופך את מניפולציית הנתונים המורכבת לבטוחה יותר.
אפשרות ההעתקה הטובה ביותר עבור הנתונים שלך
שפות תכנות רבות משתמשות במושג העתקה רדודה ועמוקת. הבנתו מאפשרת לך לתפעל נתונים ללא השלכות בלתי צפויות.
על ידי שימוש בטכניקות העתקה רדודות ועמוקות, תוכל לבחור את הגישה הטובה ביותר לשכפול מבני הנתונים שלך בבטחה. על ידי הבנת ההשפעות על הנתונים שלך, תקבל מהקוד שלך תוצאות אמינות וצפויות יותר.