0

In my code, the user inputs a text file which is saved as the variable "emplaced_animals_data." This variable has four columns (Animal ID, X location, Y location, and Z location) and the number of rows varies depending on which text file is uploaded. I then have another list (listed_animals) which contains animals that we want to gather location data about from the emplaced_animals_data. So far, I have created a new variable for each item in the listed_animals list. I want to be able to compare each of these new variables to my emplaced_items_data Animal ID column and store their appropriate locations without having to explicitly call "Animal1, Animal2, etc." Here is the code I currently have and what is being outputted:

listed_animals = ['cat', 'dog', 'bear', 'camel', 'elephant']
Animal1_Xloc = []
Animal1_Yloc = []
Animal1_Zloc = []

for i, value in enumerate(listed_animals):
    for j in range(0, len(emplaced_animals_data)):
        exec ("Animal%s=value" % (i))
        if Animal1 == emplaced_animals_data[j,0]: #don't want to explicitly have to call
            Animal1_Xloc = np.append(Animal1_Xloc, emplaced_animals_data[j,1])
            Animal1_Yloc = np.append(Animal1_Yloc, emplaced_animals_data[j,2])
            Animal1_Zloc = np.append(Animal1_Zloc, emplaced_animals_data[j,3])

print(Animal1)  
print('X locations:', Animal1_Xloc)
print('Y locations:', Animal1_Yloc)
print('Z locations:', Animal1_Zloc)

dog
X locations: ['1' '2' '3' '4' '1' '2' '3' '4' '1' '2' '3' '4' '1' '2' '3' '4' '1' '2'
 '3' '4']
Y locations: ['3' '12' '10' '8' '3' '12' '10' '8' '3' '12' '10' '8' '3' '12' '10' '8'
 '3' '12' '10' '8']
Z locations: ['9' '8' '1' '1' '9' '8' '1' '1' '9' '8' '1' '1' '9' '8' '1' '1' '9' '8'
 '1' '1']


The data being used in the emplaced_animals_data list can be found here: emplaced_animals_data visual

My goal is to plot each animals' locations with a different symbol, but because the listed_animals list may not always have the same animals or the same number of animals in it I can't call each animal explicitly. So any ideas on how I could make this iterative?

td_python
  • 25
  • 5
  • Possible duplicate of [How do I create a variable number of variables?](https://stackoverflow.com/questions/1373164/how-do-i-create-a-variable-number-of-variables) – Sayse Nov 04 '19 at 20:43
  • Any time I hear someone ask "how do I create a new variable for each..." I think: that person needs to learn about dictionaries: https://docs.python.org/3/tutorial/datastructures.html#dictionaries – jez Nov 04 '19 at 20:45
  • @jez I know... I find dictionaries very confusing and I am not sure if it will work for what I am trying to do in this instance. – td_python Nov 04 '19 at 20:50
  • @Sayse maybe? Most of what is on that page points towards using a dictionary which is something I don't really want to do/know how to do... – td_python Nov 04 '19 at 20:52
  • Dictionaries are akin to the book full of word definitions, for every word (key) there is a definition (value) – Sayse Nov 04 '19 at 20:54
  • 1
    Or, to @Sayse's point, for every key (animal) there is a value (list or tuple of locations coordinates (x,y,z)) – G. Anderson Nov 04 '19 at 20:57
  • @Sayse right... but I need to take values from one list and compare them to another list to see if the item is there and if the items is there I need to save all of its location data. So I am not sure that a dictionary would really work? – td_python Nov 04 '19 at 20:57
  • @G.Anderson ah... so how would that work if I am trying to compare the two lists? – td_python Nov 04 '19 at 20:59
  • @td_python If the reason you don't want to do it is **because** you don't know how to do it, then I strongly recommend investing effort in learning. Dictionaries are a natural solution to the type of problem you have here. To give you an idea of **how** closely they fit this use case: when you create new variables, as you seem to want to, then in Python what you're actually doing, under the hood, **is** adding entries to a dictionary—either the one returned by `globals()` or the one returned by `locals()`, depending on whether you do it outside or inside a function body. – jez Nov 04 '19 at 21:24
  • @jez I invested some effort in learning, but now I have a question regarding plotting the data using a dictionary: https://stackoverflow.com/questions/58844718/how-do-i-create-a-scatter-plot-using-data-from-two-dictionaries. – td_python Nov 13 '19 at 20:05

1 Answers1

0

See below code, I generated my own data with random numbers to mimic your data. This is just a slight modification to use numpy lists from your other question:

import numpy as np

# note that my delimiter is a tab, which might be different from yours
emplaced_animals = np.genfromtxt('animals.txt', skip_header=1, dtype=str, delimiter='   ')
listed_animals = ['cat', 'dog', 'bear', 'camel', 'elephant']

def get_specific_animals_from(list_of_all_animals, specific_animals):
    """get a list only containing rows of a specific animal"""
    list_of_specific_animals = np.array([])
    for specific_animal in specific_animals:
        for animal in list_of_all_animals:
            if animal[0] == specific_animal:
                list_of_specific_animals = np.append(list_of_specific_animals, animal, 0)
    return list_of_specific_animals

def delete_specific_animals_from(list_of_all_animals, bad_animals):
    """
    delete all rows of bad_animal in provided list
    takes in a list of bad animals e.g. ['dragonfly', 'butterfly']
    returns list of only desired animals
    """
    all_useful_animals = list_of_all_animals
    positions_of_bad_animals = []
    for n, animal in enumerate(list_of_all_animals):
        if animal[0] in bad_animals:
            positions_of_bad_animals.append(n)
    if len(positions_of_bad_animals):
        for position in sorted(positions_of_bad_animals, reverse=True):
            # reverse is important
            # without it, list positions change as you delete items
            all_useful_animals = np.delete(all_useful_animals, (position), 0)
    return all_useful_animals

emplaced_animals = delete_specific_animals_from(emplaced_animals, ['dragonfly', 'butterfly'])

list_of_elephants = get_specific_animals_from(emplaced_animals, ['elephant'])

list_of_needed_animals = get_specific_animals_from(emplaced_animals, listed_animals)
jacob
  • 828
  • 8
  • 13