<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Field Calculator - Python - Global and Local scope in Geoprocessing Questions</title>
    <link>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040856#M25360</link>
    <description>&lt;P&gt;I've used that find duplicates definition for a number of years.&amp;nbsp; &lt;A href="https://www.donmeltz.com/find-duplicate-field-values-in-arcgis-using-python/" target="_self"&gt;I found it here&lt;/A&gt;.&amp;nbsp; And I have never quite understood how it works!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Thu, 25 Mar 2021 22:12:11 GMT</pubDate>
    <dc:creator>JoeBorgione</dc:creator>
    <dc:date>2021-03-25T22:12:11Z</dc:date>
    <item>
      <title>Field Calculator - Python - Global and Local scope</title>
      <link>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040823#M25356</link>
      <description>&lt;P&gt;I recently came across something I found a bit confusing.&lt;/P&gt;&lt;P&gt;In field calculator if say I want to auto-increment a field, I can create a simple function to add 1 to a variable starting at 0, then return that value - but I have to set that variable as a global:&lt;/P&gt;&lt;LI-CODE lang="python"&gt;counter = 0
def increment():
    global counter
    counter += 1
    return counter&lt;/LI-CODE&gt;&lt;P&gt;If however I want to keep appending to a list such as to find duplicate values -&amp;nbsp;&lt;A href="https://support.esri.com/en/technical-article/000012758" target="_blank"&gt;How To: Identify duplicate field values in ArcGIS 10.x (esri.com)&lt;/A&gt;&lt;/P&gt;&lt;P&gt;The list is retained in a global scope (I guess?)&lt;/P&gt;&lt;LI-CODE lang="python"&gt;uniqueList = []
def isDuplicate(inValue):
  if inValue in uniqueList:
    return 1
  else:
    uniqueList.append(inValue)
    return 0&lt;/LI-CODE&gt;&lt;P&gt;My thinking was always that the pre-logic code block and function is executed in isolation on a per-row basis unless a global variable is set - which then (in my mind) isolates that variable from recreation each time.&lt;/P&gt;&lt;P&gt;Do I need to do some back-to-basics reading on local and global scope, or is this just an esri quirk?&lt;/P&gt;&lt;P&gt;I don't have a computer science background and am self-taught (as most probably are) and still learning every day, but would appreciate if someone could explain it, since it's bugging me.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Cheers.&lt;/P&gt;</description>
      <pubDate>Thu, 25 Mar 2021 20:38:13 GMT</pubDate>
      <guid>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040823#M25356</guid>
      <dc:creator>DavidPike</dc:creator>
      <dc:date>2021-03-25T20:38:13Z</dc:date>
    </item>
    <item>
      <title>Re: Field Calculator - Python - Global and Local scope</title>
      <link>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040832#M25357</link>
      <description>&lt;P&gt;a good bookmark&lt;/P&gt;&lt;P&gt;&lt;A href="https://docs.python.org/3/faq/programming.html" target="_blank"&gt;Programming FAQ — Python 3.9.2 documentation&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;A href="https://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python" target="_blank"&gt;Programming FAQ — Python 3.9.2 documentation&lt;/A&gt;&lt;/P&gt;&lt;P&gt;but experimentation is always the best teacher&lt;/P&gt;</description>
      <pubDate>Thu, 25 Mar 2021 21:11:53 GMT</pubDate>
      <guid>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040832#M25357</guid>
      <dc:creator>DanPatterson</dc:creator>
      <dc:date>2021-03-25T21:11:53Z</dc:date>
    </item>
    <item>
      <title>Re: Field Calculator - Python - Global and Local scope</title>
      <link>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040836#M25359</link>
      <description>&lt;P&gt;Thanks Dan, it's a handy guide.&amp;nbsp; Do you know why the list doesn't have to be set as global in the example?&lt;/P&gt;</description>
      <pubDate>Thu, 25 Mar 2021 21:23:00 GMT</pubDate>
      <guid>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040836#M25359</guid>
      <dc:creator>DavidPike</dc:creator>
      <dc:date>2021-03-25T21:23:00Z</dc:date>
    </item>
    <item>
      <title>Re: Field Calculator - Python - Global and Local scope</title>
      <link>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040856#M25360</link>
      <description>&lt;P&gt;I've used that find duplicates definition for a number of years.&amp;nbsp; &lt;A href="https://www.donmeltz.com/find-duplicate-field-values-in-arcgis-using-python/" target="_self"&gt;I found it here&lt;/A&gt;.&amp;nbsp; And I have never quite understood how it works!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 25 Mar 2021 22:12:11 GMT</pubDate>
      <guid>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040856#M25360</guid>
      <dc:creator>JoeBorgione</dc:creator>
      <dc:date>2021-03-25T22:12:11Z</dc:date>
    </item>
    <item>
      <title>Re: Field Calculator - Python - Global and Local scope</title>
      <link>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040862#M25361</link>
      <description>&lt;P&gt;The Q. "&lt;A href="https://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python" target="_self"&gt;What are the rules for local and global variables in Python&lt;/A&gt;?" in&amp;nbsp;&lt;a href="https://community.esri.com/t5/user/viewprofilepage/user-id/215600"&gt;@DanPatterson&lt;/a&gt;'s link explains:&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;SPAN&gt;If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global.&lt;/SPAN&gt;&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;In the 1st example, your global &lt;FONT face="courier new,courier"&gt;i&lt;/FONT&gt; gets&amp;nbsp;&lt;SPAN&gt;assigned a value&lt;/SPAN&gt; and thus overwritten in each loop iteration, so must be declared as a &lt;FONT face="courier new,courier"&gt;global&lt;/FONT&gt;&amp;nbsp;otherwise it would get replaced by a local variable.&lt;/P&gt;&lt;P&gt;In the 2nd example, you are not assigning a value to&amp;nbsp;&lt;FONT face="courier new,courier"&gt;uniqueList&lt;/FONT&gt; (and thus overwriting the initial global var with a local var), you are calling the append method of an existing global.&lt;/P&gt;&lt;P&gt;This is one reason I avoid globals, too easy to introduce bugs.&lt;/P&gt;</description>
      <pubDate>Fri, 26 Mar 2021 00:12:17 GMT</pubDate>
      <guid>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040862#M25361</guid>
      <dc:creator>Luke_Pinner</dc:creator>
      <dc:date>2021-03-26T00:12:17Z</dc:date>
    </item>
    <item>
      <title>Re: Field Calculator - Python - Global and Local scope</title>
      <link>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040863#M25362</link>
      <description>&lt;P&gt;&lt;EM&gt;This is one reason I avoid globals, too easy to introduce bugs.&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;As do I....&lt;/P&gt;</description>
      <pubDate>Thu, 25 Mar 2021 22:26:58 GMT</pubDate>
      <guid>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040863#M25362</guid>
      <dc:creator>JoeBorgione</dc:creator>
      <dc:date>2021-03-25T22:26:58Z</dc:date>
    </item>
    <item>
      <title>Re: Field Calculator - Python - Global and Local scope</title>
      <link>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040865#M25363</link>
      <description>&lt;P&gt;&lt;a href="https://community.esri.com/t5/user/viewprofilepage/user-id/3374"&gt;@JoeBorgione&lt;/a&gt;&amp;nbsp;has forgotten his numpy&lt;/P&gt;&lt;LI-CODE lang="python"&gt;tbl = r"C:\arcpro_npg\npg\Project_npg\npgeom.gdb\sample_10k"  # -- Joe's sample
fld = "Age"  # --
from arcpy.da import TableToNumPyArray   # --- a little import
arr = TableToNumPyArray(tbl, "Age") # --- the big 'searchcursor'
uni, cnts = np.unique(arr, return_counts=True) # --- get the unique and count
u = uni.astype(np.int)  # -- confirmation of data type
u[np.where(cnts &amp;gt; 1)[0]]  # -- a little query and voila

array([18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
       35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
       52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
       69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
       86, 87, 88, 89])&lt;/LI-CODE&gt;</description>
      <pubDate>Thu, 25 Mar 2021 22:36:02 GMT</pubDate>
      <guid>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040865#M25363</guid>
      <dc:creator>DanPatterson</dc:creator>
      <dc:date>2021-03-25T22:36:02Z</dc:date>
    </item>
    <item>
      <title>Re: Field Calculator - Python - Global and Local scope</title>
      <link>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040867#M25364</link>
      <description>&lt;P&gt;Yes, indeed....&lt;/P&gt;</description>
      <pubDate>Thu, 25 Mar 2021 22:38:08 GMT</pubDate>
      <guid>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040867#M25364</guid>
      <dc:creator>JoeBorgione</dc:creator>
      <dc:date>2021-03-25T22:38:08Z</dc:date>
    </item>
    <item>
      <title>Re: Field Calculator - Python - Global and Local scope</title>
      <link>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040871#M25365</link>
      <description>&lt;P&gt;Thanks very much Luke, I kinda just zombie-like use the += without thinking what it actually is doing.&lt;/P&gt;&lt;P&gt;I'm nearly convinced (I'm a bit slow), but can't then figure how there is there no variable referenced before assignment error if I removed the global in my first example.&lt;/P&gt;</description>
      <pubDate>Thu, 25 Mar 2021 22:55:17 GMT</pubDate>
      <guid>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040871#M25365</guid>
      <dc:creator>DavidPike</dc:creator>
      <dc:date>2021-03-25T22:55:17Z</dc:date>
    </item>
    <item>
      <title>Re: Field Calculator - Python - Global and Local scope</title>
      <link>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040872#M25366</link>
      <description>&lt;P&gt;what is this?&amp;nbsp;&lt;span class="lia-unicode-emoji" title=":face_with_tears_of_joy:"&gt;😂&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 25 Mar 2021 22:56:51 GMT</pubDate>
      <guid>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040872#M25366</guid>
      <dc:creator>DavidPike</dc:creator>
      <dc:date>2021-03-25T22:56:51Z</dc:date>
    </item>
    <item>
      <title>Re: Field Calculator - Python - Global and Local scope</title>
      <link>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040904#M25368</link>
      <description>&lt;P&gt;You're right, should've tested my example, the "&lt;FONT face="courier new,courier"&gt;+=&lt;/FONT&gt;" will fail with&amp;nbsp;&lt;FONT face="courier new,courier"&gt;UnboundLocalError: local variable 'somevar' referenced before assignment&lt;/FONT&gt;&amp;nbsp;because it's trying to create a local scope variable from a local scope variable which doesn't exist.&amp;nbsp;&lt;/P&gt;&lt;P&gt;Regardless, if you assign a value to a variable in the function without declaring it as a global, it will "shadow" (replace) the global in the function, but not update the global.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;somevar = 0

def test1():
    somevar = 111
    return somevar

def test2():
    global somevar
    somevar = 111
    return somevar

print('global', somevar, 'local', test1())
print('global', somevar, 'local', test1(), "global somevar has not changed")

print('global', somevar, 'local', test2())
print('global', somevar, 'local', test2(), "global somevar has been updated")&lt;/LI-CODE&gt;</description>
      <pubDate>Fri, 26 Mar 2021 00:25:24 GMT</pubDate>
      <guid>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1040904#M25368</guid>
      <dc:creator>Luke_Pinner</dc:creator>
      <dc:date>2021-03-26T00:25:24Z</dc:date>
    </item>
    <item>
      <title>Re: Field Calculator - Python - Global and Local scope</title>
      <link>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1041094#M25369</link>
      <description>&lt;P&gt;It has to do with lists being a mutable data type while strings, integers, floats, etc... are not mutable.&amp;nbsp; Python variables reference addresses in memory.&amp;nbsp; With CPython, the id() function returns an object's address in memory, which makes it convenient for illustrating this point about mutability.&lt;/P&gt;&lt;P&gt;Looking at two examples of immutable data types:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;&amp;gt;&amp;gt;&amp;gt; # look at memory address change when changing integer variable value
&amp;gt;&amp;gt;&amp;gt; i = 5
&amp;gt;&amp;gt;&amp;gt; id(i)
140714082966800
&amp;gt;&amp;gt;&amp;gt; i = 6
&amp;gt;&amp;gt;&amp;gt; id(i)
140714082966832
&amp;gt;&amp;gt;&amp;gt; 
&amp;gt;&amp;gt;&amp;gt; # look at memory address change when changing string variable value
&amp;gt;&amp;gt;&amp;gt; s = "foobar"
&amp;gt;&amp;gt;&amp;gt; id(s)
1355804104048
&amp;gt;&amp;gt;&amp;gt; s = "hello world"
&amp;gt;&amp;gt;&amp;gt; id(s)
1355809971568
&amp;gt;&amp;gt;&amp;gt; 
&amp;gt;&amp;gt;&amp;gt; s += ","
&amp;gt;&amp;gt;&amp;gt; s
'hello world,'
&amp;gt;&amp;gt;&amp;gt; id(s)
1355804104048
&amp;gt;&amp;gt;&amp;gt;&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;As you can see, updating a variable that stores an immutable data type updates the memory address because a new object is created and the variable pointer changed to the location of that new object.&lt;/P&gt;&lt;P&gt;Now, look at an example of a mutable data type:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;&amp;gt;&amp;gt;&amp;gt; l = [5]
&amp;gt;&amp;gt;&amp;gt; id(l)
1355802301384
&amp;gt;&amp;gt;&amp;gt; l[0] = 6
&amp;gt;&amp;gt;&amp;gt; id(l)
1355802301384
&amp;gt;&amp;gt;&amp;gt;
&amp;gt;&amp;gt;&amp;gt; l.append("foobar")
&amp;gt;&amp;gt;&amp;gt; l
[6, 'foobar']
&amp;gt;&amp;gt;&amp;gt; id(l)
1355802301384
&amp;gt;&amp;gt;&amp;gt;&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;As the list is updated and modified, the memory address for the entry point into that list remains the same even though the contents within the list change.&amp;nbsp; Mutable.&lt;/P&gt;&lt;P&gt;When a list is used as a parameter in a function, any modifications of it in the function are seen by outside/calling namespaces because the memory address for the list has not changed with the changes made within the function.&lt;/P&gt;&lt;P&gt;When an immutable data type is used as a parameter in a function, the local namespace of the function inherits the pointers to variable memory addresses and can use the values stored in those addresses.&amp;nbsp; When a function modifies the inherited variable, the function cannot modify the global namespace to update the pointer so only the local namespace knows of the new memory address to the updated value.&lt;/P&gt;&lt;P&gt;The global keyword tells the Python parser that the function can or is allowed to modify the outside/calling namespace for the variable with that keyword.&amp;nbsp; I guess you could look at it as the global keyword merges the global and local namespaces for the variable in question, so when the function updates the variable and changes the pointer to a new memory address, the calling namespace sees the new memory address and value.&lt;/P&gt;</description>
      <pubDate>Fri, 26 Mar 2021 16:06:09 GMT</pubDate>
      <guid>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1041094#M25369</guid>
      <dc:creator>JoshuaBixby</dc:creator>
      <dc:date>2021-03-26T16:06:09Z</dc:date>
    </item>
    <item>
      <title>Re: Field Calculator - Python - Global and Local scope</title>
      <link>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1041224#M25370</link>
      <description>&lt;P&gt;Excellent, I can see what's going on with that ID function perfectly.&amp;nbsp; Still gives me a headache though.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks all.&lt;/P&gt;</description>
      <pubDate>Fri, 26 Mar 2021 20:56:52 GMT</pubDate>
      <guid>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1041224#M25370</guid>
      <dc:creator>DavidPike</dc:creator>
      <dc:date>2021-03-26T20:56:52Z</dc:date>
    </item>
    <item>
      <title>Re: Field Calculator - Python - Global and Local scope</title>
      <link>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1041226#M25371</link>
      <description>&lt;P&gt;Thanks Luke.&lt;/P&gt;&lt;P&gt;global 0 local 111&lt;BR /&gt;global 0 local 111 global somevar has not changed&lt;BR /&gt;global 0 local 111&lt;BR /&gt;global 111 local 111 global somevar has been updated&lt;/P&gt;</description>
      <pubDate>Fri, 26 Mar 2021 20:57:49 GMT</pubDate>
      <guid>https://community.esri.com/t5/geoprocessing-questions/field-calculator-python-global-and-local-scope/m-p/1041226#M25371</guid>
      <dc:creator>DavidPike</dc:creator>
      <dc:date>2021-03-26T20:57:49Z</dc:date>
    </item>
  </channel>
</rss>

