0

I have a class like this...

class person:
    def __init__(self, name):
        self.name = name
        self.carData = ""        
        self.HouseData = ""
        #other assets 

And I'm looping through it like this...

john = person('John');
for index, row in john.carData.iterrows():
    #do something

for index, row in john.HouseData.iterrows():
    #do something

But in this case "do something" is repetitive code - I want to do the same thing for carData, HouseData and all the other assets a person can own.

What's the best way to loop through these in a non-repetitive way? I was thinking of something like this in the class definition but I'm pretty sure it's at least inelegant and probably wrong...

class person:
    def __init__(self, name):
        self.name = name
        self.carData = ""        
        self.HouseData = ""
        #other assets 
        self.assets = [self.carData, self.HouseData etc]

john = person('John');

for asset in john.assets:
    for index, row in asset.iterrows():
        #do something

Is that bad practise to define a list of objects (in this case self.assets) that itself refers to the same objects stored in the class? Apologies if this is vague - I'm just trying to figure out the cleanest way to deal with this scenario.

d3wannabe
  • 1,207
  • 2
  • 19
  • 39
  • 1
    It's a bad idea to declare each of those _assets_ as strings in the first place, especially since (i presume) you want to use `DataFrame` in their place. Second, you can use `map()`/`reduce()`/`filter()` for a more elegant approach but that would heavily depend on `#do something` code... – zwer Jan 27 '19 at 06:54
  • 1
    Instead of defining `asset` as an attribute of `john`, why not just `for asset in (john.carData, john.HouseData): ...` ? – alkasm Jan 27 '19 at 08:12

1 Answers1

1

If you plan on applying the same code to every attribute of your object, you can try john.__dict__:

john = person('John')
for attr, value in john.__dict__.items():
    # e.g. attr == 'carData'
    for index, row in value.iterrows():
        # do something

See this question.

It's kind of hackish, but if (for example) you want to apply the code to every attribute except "name", do this:

john = person('John')
for attr, value in john.__dict__.items():
    # e.g. attr == 'carData'
    if attr != 'name':
        for index, row in value.iterrows():
            # do something
Kyle
  • 1,070
  • 2
  • 13
  • 23