3

I have a constants file constants.py like so:

querystring = {
    "limit":"10000",
    "sort":"desc"
}

dummy1 = {
    "a": "22",
    "q": "*",
}

dummy2 = {
    "a": "24",
    "q": "**",
}

streams = [dummy1, dummy2]

I'm trying to initialise a list by manipulating the values from the constants.py file.

from constants import querystring, streams
def setParams(dummy, querystring):
    ld = {}
    ld["query"] = setQuerystring( dummy, querystring)
    print ld
    return ld

def setQuerystring( dummy, querystring):
    query = querystring
    query["filter"] = "stream:" + dummy["a"]
    query["query"] = dummy["q"]
    return query

l = map(lambda x: setParams(x, querystring), streams)
print l[0]
print l[1]

While the lambda function is running, the output is correctly printed, but when I see the final value returned by the map, the values are different. Why this inconsistency?

The program output:

{'query': {'sort': 'desc', 'filter': 'stream:22', 'limit': '10000', 'query': '*'}} # l[0] -> during lambda execution
{'query': {'sort': 'desc', 'filter': 'stream:24', 'limit': '10000', 'query': '**'}} # l[1] -> during lambda execution
{'query': {'sort': 'desc', 'filter': 'stream:24', 'limit': '10000', 'query': '**'}} # l[0] -> from map 
{'query': {'sort': 'desc', 'filter': 'stream:24', 'limit': '10000', 'query': '**'}} # l[1] -> from map
1
  • querystring is in fact mutable dict. query = querystring does not create a copy of dict, but uses reference instead. In setQuerystring you modify same dict instance over and over again. Try query = querystring.copy() Commented Jul 17, 2017 at 13:58

1 Answer 1

3

You're reusing and modifying the querystring dict across iterations. Later changes from successive iterations are therefore propagated to previously attached copies. You should consider attaching a copy to each dict instead, and modifying that copy:

def setQuerystring( dummy, querystring):
    query = querystring.copy()
    ...

{'query': {'sort': 'desc', 'filter': 'stream:22', 'limit': '10000', 'query': '*'}}
{'query': {'sort': 'desc', 'filter': 'stream:24', 'limit': '10000', 'query': '**'}}
{'query': {'sort': 'desc', 'filter': 'stream:22', 'limit': '10000', 'query': '*'}}
{'query': {'sort': 'desc', 'filter': 'stream:24', 'limit': '10000', 'query': '**'}}
Sign up to request clarification or add additional context in comments.

1 Comment

I was under the assumption that the default behaviour was to copy, not change the existing object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.