murtourpo95
murtourpo95

Reputation: 85

Setting dictionary value in python does not update the value?

I am trying to simply replace missing date values from two strings, but splitting them into a dictionary of "year", "month", etc. However I am running into a very odd issue I did not find the answer for after 20 minutes googling.

Here's my code:

def date_split(date):
    parts = date.split('-')
    if len(parts) == 1:
        year = parts[0]
        dates = {'y' : year}
    if len(parts) == 2:
        year = parts[0]
        month = parts[1]
        dates = {'y' : year, 'm' : month}
    if len(parts) == 3:
        year = parts[0]
        month = parts[1]
        day = parts[2]
        dates = {'y' : year, 'm' : month, 'd' : day}
    return dates

def recompile(date):
    lista = list(date.values())
    date = "-".join(lista)
    return date

std = "2018-07-18"
x = "XXXX-01"

if date_split(x)['y'] == 'XXXX':
    new = str(date_split(std)['y'])
    date_split(x)['y'] = new
    date = recompile(date_split(x))
    print(date)

I just began twiddling with it so it's very rough, but I am working on it. However, while date_split(std)['y'] prints out as 2018, after date_split(x)['y'] = new, the value of date_split(x)['y'] prints out as "XXXX" still. So the dictionary does not update the value. Is there something I'm missing about how dictionaries work in python? I'm quite new to it. I've tried also different forms of the dictionary update command.

Using Python 3.6 with Anaconda.

Upvotes: 2

Views: 3024

Answers (4)

PM 2Ring
PM 2Ring

Reputation: 55469

As others have said you need to save the dictionary returned by date_split so you can modify it. However, your date_split function is much larger than it needs to be, so I've written a more compact version using zip.

Your recompile function won't always work correctly on earlier versions of Python, where a dict is an unordered collection, but it's ok on Python 3.6+ since dict now retains the insertion order. Also, there's no need to call str in new = str(date_split(std)['y']). All the values in the dict returned by date_split are already strings.

def date_split(date):
    return dict(zip("ymd", date.split("-")))

def recompile(date):
    return "-".join(date.values())

std = "2018-07-18"
x = "XXXX-01"

x_split = date_split(x)
print("Original", x_split)
if x_split["y"] == "XXXX":
    x_split["y"] = date_split(std)["y"]
    print("Updated ", x_split)
    date = recompile(x_split)
    print("String  ", date)

output

Original {'y': 'XXXX', 'm': '01'}
Updated  {'y': '2018', 'm': '01'}
String   2018-01

Upvotes: 1

Hadi Farah
Hadi Farah

Reputation: 1162

def date_split(date):
    parts = date.split('-')
    if len(parts) == 1:
        year = parts[0]
        dates = {'y' : year}
    if len(parts) == 2:
        year = parts[0]
        month = parts[1]
        dates = {'y' : year, 'm' : month}
    if len(parts) == 3:
        year = parts[0]
        month = parts[1]
        day = parts[2]
        dates = {'y' : year, 'm' : month, 'd' : day}
    return dates

def recompile(date):
    lista = list(date.values())
    date = "-".join(lista)
    return date

std = "2018-07-18"
x = "XXXX-01"

if date_split(x)['y'] == 'XXXX':
    old = date_split(x)
    new = str(date_split(std)['y'])
    print(old)
    print(new)
    old['y'] = new
    date = recompile(old)
    print(date)

you cannot save changes on a function call, you have to store it in a variable.

Upvotes: 1

blhsing
blhsing

Reputation: 106445

Each time you call date_split(x) it returns a new dict, so updating it won't have an effect on the next call. Instead, you should assign the returning value of date_split(x) to a variable and then use that variable for further processing.

std = "2018-07-18"
x = "XXXX-01"
s = date_split(x)
if s['y'] == 'XXXX':
    new = str(date_split(std)['y'])
    s['y'] = new
    date = recompile(s)
    print(date)

Upvotes: 1

blue note
blue note

Reputation: 29071

You change the return value of a function. Since you don't store it anywhere, it's lost. Instead, do something like

 custom_date = date_split(x)
 custom_date['y'] = new
 date = recompile(custom_date)

Upvotes: 1

Related Questions