-2

I have created a python function which contains a for loop combined with if statements to iterate over each element in an array to find the word 'Urban' contained within the string and returns a positive index if found, otherwise returns -1 should the value not exist within the string. Below is an example of the output:

abc = np.array(crew_data['Vegetation Area'])
print(abc)
-1
 2 
-1
10
10
10

Following this the loop proceeds to execute the following if statements:

if abc == -1:
  abc = str('Rural')
elif abc != -1:
  abc != str('Urban')
return(abc)

What is happening here is, based on the results of the array iteration, any result returning the value -1 is assigned the string value 'Rural', and anything not equal to -1 is assigned the string value of 'Urban. Below is the result when printed:

 print(abc)
 Rural
 Urban
 Rural
 Urban
 Urban
 Urban

As the example demonstrates, the function when called performs the loop and if statements, and returns the result as required, however when this function is called within another for loop the results change and it appears that the loop (in question) continues to reiterate and produces the incorrect result. Initially I thought it could have been contributed to using the same iterator of i which is used in the later for loop, so I changed the iterator value to x, and nothing has changed.

Note that the later for loop mentioned (code not shown) calls on a number of different functions without a problem, however, this is the only function which contains a for loop.

Are there any additional controls that need to be integrated into the function that will allow it to correctly execute within the later for loop?

FYI, below is the function code referenced in this question:

def area_type():
  abc= np.array(crew_data['Vegetation Area'])
  for x in abc:
      abc = x.find('Urban') 
      if abc == -1:
          abc = str('Rural')
      elif abc != -1:
          abc = str('Urban')
      return abc

Below is the output of the original array before the value has been converted:

 'V-Wellington 906' 'V-Wellington 906' 'V-Urban Narromine 530_1'
 'V-Tumbarumba - 78545 - Taradale' 'V-Tumut - Urban Batlow'     
 'V-Tumut - Urban Batlow' 'V-Tumut - Urban Batlow'
 'V-Tumut - Urban Batlow' 'V-Tumut - Urban Batlow'
 'V-Tumut - Urban Batlow' 'V-Tumut - Urban Batlow'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 3'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 3'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumut - 78245+78244+78240 - Back Kunama' 'V-Tumut - Urban Batlow'
 'V-Tumut - Urban Batlow' 'V-Tumut - Urban Batlow'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumut - 78245+78244+78240 - Back Kunama'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 - Ournie Feeder C'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 - Ournie Feeder C'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 - Ournie Feeder C'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumut - 78245+78244+78240 - Back Kunama'
 'V-Tumut - 78245+78244+78240 - Back Kunama'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumut - 78245+78244+78240 - Back Kunama'
 'V-Tumbarumba - 78510 - Ournie Feeder C'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumut - 78245+78244+78240 - Back Kunama'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78514 - Jingellic' 'V-Tumbarumba - 78514 - Jingellic'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78514 - Jingellic' 'V-Tumbarumba - 78514 - Jingellic'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B'
 'V-Tumbarumba - 78514 - Jingellic'
 'V-Tumbarumba - 78510 + 78513 - Ournie Feeder B' 'V-Tumut - Urban Batlow'
 'V-Tumut - Urban Batlow' 'V-Tumbarumba - 78520 + 78521 - Tooma Part 2'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78540 +78547 - Laurel Hill'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumbarumba - 78520 + 78521 - Tooma Part 1'
 'V-Tumut - 78316 - Talbingo' 'V-Tumut - Urban Talbingo'
 'V-Tumut - 78316 - Talbingo' 'V-Tumut - 78316 - Talbingo'
 'V-Tumut - 78316 - Talbingo' 'V-Tumut - 78316 - Talbingo'
 'V-Tumut - 78316 - Talbingo'
 'V-Gundagai - 78440+78442+78444 - Tumblong Part 2'
 'V-Gundagai - 78440+78442+78444 - Tumblong Part 2'
 'V-Gundagai - 78440+78442+78444 - Tumblong Part 2'
 'V-Gundagai - 78440+78442+78444 - Tumblong Part 2'
 'V-Tumbarumba - 78510+78511+78512 - Ournie Feeder A'
 'V-Tumbarumba - 78510+78511+78512 - Ournie Feeder A']

This array is extracted from a column of the imported csv file which is stored as a pandas DataFrame. The function presented in this post is required to iterate through that array, search for the word urban, return an index or boolean, convert that value to either Urban or Rural, then be returned and called upon in a later loop to populate the range in the empty dataframe which will then be exported as a csv ready to be imported into another database.

jasw
  • 33
  • 2
  • 7
  • 2
    don't say `for x in abc` and then reassign abc, bad joojoo – SuperStew Jan 29 '20 at 23:17
  • 3
    An unconditional `return` statement in a loop makes the loop pointless - only one iteration will take place. – jasonharper Jan 29 '20 at 23:17
  • 7
    This seems like an [xy problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). It might be better to explain what you're trying to accomplish, because it looks like you actually need a solution using `np.where()` but it's tough to say – G. Anderson Jan 29 '20 at 23:18
  • When the condition in `elif` is the exact opposite of the `if` condition, you should use `else:`. – Barmar Jan 29 '20 at 23:29
  • `abc != str('Urban')` does nothing useful. It compares `abc` to (the unnecessary casted string) `'Urban'` but throws away the result because you don't do anything with it. – Jongware Jan 29 '20 at 23:30
  • @PacketLoss It won't impact the loop. `for x in y` only evaluates `y` once at the beginning, not every iteration. – Barmar Jan 29 '20 at 23:30
  • @Barmar indeed, i just double checked. i overlooked this due to the `return`, fixed :) – PacketLoss Jan 29 '20 at 23:31
  • @usr2564301 I think that's just a typo in the question, it's not in the `area_type()` function at the bottom. – Barmar Jan 29 '20 at 23:33
  • I agree with @G.Anderson, we need more information. – AMC Jan 30 '20 at 00:48
  • This is only one function within the script. The actual script itself takes an imported csv file from one database, populates an empty DataFrame then exports it as a csv ready to import into another database. The functions contained within the script are used to reference and convert values from the imported csv then use those values as input to populate the empty DataFrame – jasw Jan 30 '20 at 01:44
  • I'm only new to Python, and have only been using it now for about 4 weeks. I am converting from Excel due to the size and complexity of the data which we are handling. Typically this would be quite easily handled in Excel, however with the number of formulas and tabs containing different datasets an Excel workbook is becoming slow and time consuming – jasw Jan 30 '20 at 04:27

1 Answers1

2

You are calling a blanket, unconditional return in the first loop, returning only the first result. Remember, return exits the function! Yield & Return

There is however, a fairly simple way to perform this. Given you seem to be passing an array, you likely would need the result to be returned as a list. I've set my data set as a list, as you have not provided an example of your array!

abc = ['Urban', '1', '2', '3', '5', 'Urban']
result = ['Urban' if value.find('Urban') != -1 else 'Rural' for value in abc]

result
['Urban', 'Rural', 'Rural', 'Rural', 'Rural', 'Urban']

This may be a great opportunity to do some reading on return and yield as well as list comprehension.

PacketLoss
  • 5,561
  • 1
  • 9
  • 27
  • How and where would I add yield, in replacement of return? I did this and I was presented with 'TypeError: object of type 'generator' has no len()' . What does this error mean? Is this even the correct approach to be taking to achieve was is required, after all this could be simply solved with a dictionary and a function which maps value and returns the result. – jasw Jan 30 '20 at 04:40
  • The reason i mention `yield` as well is it is another way of returning a result from a function. May not be the answer you're looking for here. You can use the above code, and `return` the list to achieve what you're looking for. – PacketLoss Jan 30 '20 at 04:44
  • I have just updated my question to include the original array – jasw Jan 30 '20 at 04:46
  • A question I do is that when the function is called inside the second loop and the dataframe is exported, the only result passed to the second loop and exported to the csv file is Rural, Urban is omitted – jasw Jan 30 '20 at 05:12
  • It appears that this is not as straight forward or simple to do. I have resolved this by simply adding an area column in the csv file and performing a search on the string value with the following formula: =IFERROR(IF(SEARCH("Urban",P2),"Urban"),"Rural") – jasw Jan 30 '20 at 05:59