G-XR8P2XJ088

AI-Written Python: A Copied List Can Still Share Records

The request sounds sensible: make a working copy of the catalogue, try a price change and leave the original alone. The AI-written script includes a copy operation. It runs successfully. Yet the price in the original data changes too.

The problem lies in what was copied. A fresh outer list can still contain references to the very same product records. For anyone commissioning a small Python workflow, “work on a copy” needs a more precise meaning: which objects must become independent, and which changes must leave the source untouched?

A second name is not a second object

Python’s official copy documentation explains that assignment binds a name to an object; it does not copy that object. A shallow copy creates a new container while retaining references to contained objects. A deep copy recursively copies contained objects, subject to the copying behaviour of their types.

Begin with a fictional catalogue containing two product records. Each record is a dictionary with an identifier, a price and a list of tags. The first record is {'id': 'P101', 'price': 12, 'tags': ['print']}; the second is {'id': 'P102', 'price': 18, 'tags': ['card']}. These are invented values used for the checks below.

Call the outer list original. In the first executed check, working = original made both names refer to the same list. Appending a third record through working left original with three records too. Renaming the route to the data had created no separation.

That result matters when reviewing an explanation from an AI assistant. A variable called “backup”, “preview” or “working” expresses an intention. It does not establish the behaviour of the object assigned to it.

A new list can still share its records

The Python data-structures tutorial identifies list.copy() as a shallow copy. Its promise concerns the list, rather than independent copies of everything stored inside it.

For the next check, the original two-record catalogue was recreated from scratch. The code used working = original.copy(). Appending a third product now increased only the working list’s length: three records in the working list, two in the original.

That test might appear to confirm the brief. But the next operation changed a field inside the first shared dictionary: working[0]['price'] = 10. The original catalogue’s first price also became 10.

The check confirmed both parts of the relationship. The outer lists were different objects, while their first records were the same object. A successful test of adding a record had not tested the independence of an existing record.

For the hypothetical catalogue owner, that distinction is practical. A script preparing a promotional version might correctly add temporary products without altering the source list’s membership, yet still alter source prices while adjusting existing products.

Copying each row reaches one level further

A third check again started with fresh source data. This time the working list was built with working = [row.copy() for row in original]. Each product dictionary received a shallow copy of its own.

Changing the working price to 10 now left the original price at 12. However, adding a nested tag with working[0]['tags'].append('sale') changed the original tags to ['print', 'sale'] as well.

The executed identity checks showed different first-record dictionaries but the same nested tags list. The attempted separation had moved down one level, while the tags remained shared.

This is why a review should exercise the actual planned edits. A workflow that only replaces a price needs a different independence check from one that also appends tags, changes nested options or updates a list of image references. Test the operation the business intends to perform.

Deep copying worked for this example

In a fourth check, the catalogue was recreated and copied using working = copy.deepcopy(original), after importing Python’s copy module. The same working price change and tag addition left the original price at 12 and its tags at ['print']. The working version contained price 10 and tags ['print', 'sale'].

That result supports a specific conclusion: deep copying separated the mutable containers needed for these edits in this small example of built-in lists and dictionaries. It does not establish that an entire production application has been isolated.

The copy documentation also cautions that deep copying can copy more than intended and allows custom classes to control copying. It excludes certain resources, including files and sockets. Treat the intended data structure as part of the design, rather than adding deep copying to every script by habit.

For this fictional catalogue, I would ask the developer to identify exactly what the working version may change. They can then choose deep copying or construct the required independent output explicitly, and demonstrate that choice against representative data.

Turn source preservation into an acceptance check

A clearer brief would say: create a promotional catalogue in memory; change selected prices and add promotional tags there; keep all values and nested tag lists in the source catalogue unchanged.

Ask for checks that match those promises:

  • Adding or removing a working record must leave source membership unchanged.
  • Replacing a working price must leave the corresponding source price unchanged.
  • Appending a working tag must leave the corresponding source tags unchanged.
  • The finished working output must still contain the intended identifiers and values.
  • Each check must begin with fresh source data so an earlier mutation cannot distort the next result.

Source preservation is one requirement among several. MaryChuks’ guide to checking lists before pairing records examines another: whether all expected inputs survive the combination. A workflow can preserve its source and still produce an incomplete output, so verify both promises separately.

Know what the test has established

The examples described here were executed in Python 3.12.14. They checked assignment, a copied outer list, copied dictionaries with shared nested tags, and deep copying of the sample catalogue. No shop platform was connected and no live product data was changed.

Copying these in-memory objects is also a different operation from preserving an exported file or reversing an external update. If a later stage writes prices to a shop, that stage needs its own review and recovery design.

The useful question for AI-written code is concrete: after this proposed edit, what must remain unchanged? Name that boundary, run the actual mutation against a small example and inspect the source afterwards. A reassuring variable name becomes a meaningful promise only when the behaviour supports it.

Sources


Discover more from Marychuks.com AI, Psychology, Business & CreativeVerse

Subscribe to get the latest posts sent to your email.

Leave a Reply

Discover more from Marychuks.com AI, Psychology, Business & CreativeVerse

Subscribe now to keep reading and get access to the full archive.

Continue reading