pythondataframelistclassnested-loops

Reducing length with a loop


I have a class which has a series of loops inside of it. Each loop uses a pandas.dataframe to add data to a new list that can be called as an instance attribute.

data = [player_stats, captured_creatures, item_list, moveset, opponents_stats, player_inventory]

class Battle():
    def __init__(self,data):

        stuff,stuff1,stuff2,stuff3,stuff4,stuff5 = [], [], [], [], [], []

        for t in data.player_stats.loc[0, :]:
            stuff.append(t)
        for t in data.captured_creatures.loc[0, :]:
            stuff1.append(t)
        for t in data.item_list.loc[0, :]:
            stuff2.append(t)
        for t in data.moveset.loc[0, :]:
            stuff3.append(t)
        for t in data.opponents_stats.loc[0, :]:
            stuff4.append(t)
        for t in data.player_inventory.loc[0, :]:
            stuff5.append(t)

        self.stuff = stuff
        self.stuff1 = stuff1
        self.stuff2 = stuff2
        self.stuff3 = stuff3
        self.stuff4 = stuff4
        self.stuff5 = stuff5

Is there a way that I can reduce the repetition in this? I know I can get the instance names using:

instances = [attr for attr in dir(data)][-6:]

I am unsure how to use that information to create a nested loop.

I hope this is clear.


Solution

  • I am not sure if your data are independent pandas dataframes so data would be a pandas df array. Therefore you can just summarize with the setattr method. Here an example:

    # Sample data setup
    player_stats = pd.DataFrame({
        'HP': [100],
        'Attack': [50],
        'Defense': [40]
    })
    
    captured_creatures = pd.DataFrame({
        'Name': ['Dragon'],
        'Level': [10],
        'Type': ['Fire']
    })
    
    item_list = pd.DataFrame({
        'Item': ['Potion', 'Elixir'],
        'Quantity': [3, 1]
    })
    
    moveset = pd.DataFrame({
        'Move': ['Fireball', 'Slash'],
        'Power': [40, 30]
    })
    
    opponents_stats = pd.DataFrame({
        'HP': [120],
        'Attack': [60],
        'Defense': [45]
    })
    
    player_inventory = pd.DataFrame({
        'Gold': [500],
        'Keys': [2],
        'Potions': [1]
    })
    
    # Combine the data into a list
    data = [player_stats, captured_creatures, item_list, moveset, opponents_stats, player_inventory]
    fields = ['player_stats', 'captured_creatures', 'item_list', 'moveset', 'opponents_stats', 'player_inventory']
    
    # Define the Battle class
    class Battle():
        def __init__(self, data):
            for name, df in zip(fields, data):
                setattr(self, f"{name}", df.loc[0].tolist())
    
    # Instantiate a Battle
    battle = Battle(data)
    
    # Display the results
    print("Player Stats:", battle.player_stats)
    print("Captured Creatures:", battle.captured_creatures)
    print("Item List:", battle.item_list)
    print("Moveset:", battle.moveset)
    print("Opponents Stats:", battle.opponents_stats)
    print("Player Inventory:", battle.player_inventory)
    

    Hope it helps!