Shaun22
Shaun22

Reputation: 27

Python Changing value in JSON file

I am trying to update the actors list in a JSON file. I am using a for loop to grab the list of actors but when I try updating the list with an if clause, the output is unchanged. I want to change "Alan Arkin" to "John Doe"

The output that I am getting now is: "actors": ["Ethan Hawke", "Uma Thurman", "Alan Arkin", "Loren Dean"]

The desired out put would be: "actors": ["Ethan Hawke", "Uma Thurman", "John Doe", "Loren Dean"]

This is what is inside "movie_1.txt" file

{ "title": "Gattaca", "release_year": 1997, "is_awesome": true, "won_oscar": false, "actors": ["Ethan Hawke", "Uma Thurman", "Alan Arkin", "Loren Dean"], "budget": null, "credits": { "director": "Andrew Niccol", "writer": "Andrew Niccol", "composer": "Michael Nyman", "cinematographer": "Slawomir Idziak" } }

What my code looks like right now. My issues is the for loop with a nested if clause that grabs the name in the list. The for loop through the list and the if clause should grab an instance of "Alan Arkin" and change it to "John Doe"

path = 'movie_1.txt'
import json

json_file = open(path, encoding="utf-8")
movie = json.load(json_file)
json_file.close()

print(movie['actors']) # prints unchanged list

for x in movie["actors"]:
   if x == 'Alan Arkin':
     x = 'John Doe'

print(movie['actors']) # prints changed list

Upvotes: 2

Views: 63

Answers (1)

Wizard.Ritvik
Wizard.Ritvik

Reputation: 11612

Strings are immutable types in Python, so re-assigning a loop variable that is a string won't work as intended. Btw, the known mutable types are list, dict, and set. Not entirely sure, but I guess what happens is you're creating a new local variable x and assigning to it. That variable is only local to each loop iteration, so that won't actually update the list.

Here's a working solution below using a simple list comprehension to build a new list with the desired actor names replaced:

import json


movies_json = """
{ "title": "Gattaca", "release_year": 1997, "is_awesome": true, "won_oscar": false, "actors": ["Ethan Hawke", "Uma Thurman", "Alan Arkin", "Loren Dean"], "budget": null, "credits": { "director": "Andrew Niccol", "writer": "Andrew Niccol", "composer": "Michael Nyman", "cinematographer": "Slawomir Idziak" } }
"""

movie = json.loads(movies_json)

print(movie['actors']) # prints unchanged list

# Note the old code:
# for x in movie["actors"]:
#    if x == 'Alan Arkin':
#      x = 'John Doe'

# Do a list comprehension (build a *new* list with the replaced values)
actor_repls = {'Alan Arkin': 'John Doe'}
actors = [actor_repls.get(actor, actor) for actor in movie['actors']]
# You can re-assign it if you want, though it's technically not needed
# movie['actors'] = actors

print(actors)   # prints changed list
# prints:
#   ['Ethan Hawke', 'Uma Thurman', 'John Doe', 'Loren Dean']

Upvotes: 1

Related Questions