title: Python loop through a list to find a substring match in another string from a column in dataframe then return that matched substring in a new column
body: <p>I am programming in Python 3.6 on Spyder 3.2.3 on MacOS Sierra 10.12.6.</p>
  
  <p>I have a column in a dataframe <code>df</code> containing a list of towns in Australia and other information. The column of interest is <code>suburbs</code></p>
  
  <pre><code>df["suburbs"]
  
  Apollo Bay (Tas.)
  Apollo Bay (Vic.)
  Apoinga
  ACT Remainder - Belconni
  </code></pre>
  
  <p>I also have a list <code>states</code> containing the states in Australia.</p>
  
  <pre><code>states = ["NSW", "VIC", "TAS", "ACT", "SA", "WA"]
  </code></pre>
  
  <p>My objective is to see whether a suburb from the <code>df["suburbs"]</code>contains any state from the list <code>states</code> and if yes, then it will return the state in column <code>df["state"]</code>.</p>
  
  <p>So, at the moment my solution is to use for loop and if statement, however, for some reason my for loop and if statement returns <code>not found</code> to every line even if it matches. My current for loop and if statement is below:</p>
  
  <pre><code>for suburb in df["suburbs"].str.upper():
      for state in states:
          if state in suburb:
              df["state"] = state
          else:
              df["state"] = "not found"
  </code></pre>
  
  <p>And this returns</p>
  
  <pre><code>not found
  not found
  not found
  not found
  </code></pre>
  
  <p>Another thing I noticed is on the variable explorer section of the Spyder, the above code creates 2 variables <code>suburb</code> and <code>state</code> with values <code>ACT Remainder - Belconni</code> and <code>WA</code>, respectively. It seems to pick the last values from both the dataframe column and list.</p>
  
  <p>However, if I do not create a new column <code>state</code> and just use <code>print</code> function to see if the substring matches, it shows that it actually works. Code is below:</p>
  
  <pre><code>for suburb in test["suburbs"].str.upper():
      for state in states:
          if state in suburb:
              print(suburb, state)
  </code></pre>
  
  <p>And the result is:</p>
  
  <pre><code>APOLLO BAY (TAS.) TAS
  APOLLO BAY (VIC.) VIC
  ACT REMAINDER - BELCONNI ACT
  </code></pre>
  
  <p>It skips the one that doesn't have the match. But as soon as I add an additional <code>else</code> statement to print <code>not found</code> the result will be all <code>not found</code>. Can anyone please help me understand what is wrong here and why? It's pretty frustrating because it seems to me to be a simple task.</p>
  
  <p>Thank you so much.</p>