0

In python, I have a class that contains a list as one of its members.

class fan_details:
    name = ""
    previous_addresses = []
    age = 0


fans = []

x.name = "Joe Blow"
x.previous_address.append("4, seaview rd")
x.age = 42;
fans.append(x)

x.previous_address.pop(0)

x.name = "Jimmy Flag"
x.previous_address.append("21, Main Street")
x.age = 33;
fans.append(x)

print fans[0].previous_address
print fans[1].previous_address

The two last print statements would print out "21, Main Street". It looks like the append() is like a pointer in C as the fans[0].previous address is the same as fans[1].previous address.

Is there a way of keeping fans[0].previous_address to "4, seaview rd"?

Please bear with me as I am a noob in Python.

Thanks in advance.

tehnyit
  • 1,152
  • 1
  • 9
  • 16

4 Answers4

2

There were a few problems:

  1. spelling errors (previous_addresses vs previous_address)
  2. you were not initializing the "self", in other words, when you request a new fan_details object, you were not creating new fan_details objects
  3. related to #2, you were not calling for the new object to be created. You need two objects to be created for this example.
  4. you were popping the address of your fan_details object, but because fans[0] and fans[1] pointed to the same object you were basically overwriting all the values of fans[0], and creating two references to it.

fixed code:

class fan_details:
    #you need to initialize and define the object:
    def __init__(self, name="", previous_address = None, age = 0):
        self.name = name
        if previous_address is None:
            self.previous_addresses = []
        else:
            self.previous_addresses = [previous_address]
        self.age = age


fans = []
x = fan_details()
x.name = "Joe Blow"
x.previous_addresses.append("4, seaview rd")
x.age = 42;
fans.append(x)
#a python object is mutable!!! This means that "x" and fans[0] point to the same
#python object. Lets create a new python object:
x = fan_details(name = "Jimmy Flag", previous_address="21, Main Street", age=33)
#this line above is really important! Note that now we can initialize an object on one line :-)
fans.append(x)    
print fans[0].previous_addresses
print fans[1].previous_addresses
mgoldwasser
  • 14,558
  • 15
  • 79
  • 103
1

Your original class was not using self so all the variables were bound to the class definition and shared across all instances.

Following piece of code is defining __init__ method serving as constructor.

class FanDetails():
    def __init__(self, name="", previous_address=None, age=0):
        self.name = name
        self.previous_addresses = []
        if previous_address:
            self.previous_addresses.append(previous_address)
        self.age = age

Prepare list of fans:

fans = []

and now the trick: create an instance of FanDetails for John:

john = FanDetails("Joe Blow", "4, seaview rd", 42) 
fans.append(john)

and do the same for Jimmy:

jimmy = FanDetails("Jimmy Flag", "21, Main Street", 33) 
fans.append(jimmy)

Key difference from your original code is, these john and jimmy instances live independently, each having self value not being shared across all instances, but being root of instance privacy.

Finally check, that these two guys really do not share more, than reasonable:

print fans[0].previous_addresses
print fans[1].previous_addresses

You shall see:

['4, seaview rd']
['21, Main Street']
Jan Vlcinsky
  • 42,725
  • 12
  • 101
  • 98
0

I believe you have three problems:

  1. a typo
  2. a need to instantiate x as an instance of your class
  3. No need to pop anything if you want to keep these things as a history

my changes in the code would then look like:

class fan_details:
    name = ""
    previous_addresses = []
    age = 0


fans = []

x = fan_details()    

x.name = "Joe Blow"
x.previous_addresses.append("4, seaview rd") # <--- You had x.previous_address.append("4, seaview rd")
x.age = 42;
fans.append(x)

# x.previous_address.pop(0)

x = fan_details()    
x.name = "Jimmy Flag"
x.previous_addresses.append("21, Main Street") # <--- You had x.previous_address.append("21, Main Street")
x.age = 33;
fans.append(x)

print fans[0].previous_addresses  # add the 'es'
print fans[1].previous_addresses  # add the 'es'

You need to be consistent in the variable name you used in your class definition and the name you use when accessing it.

  • You are right, that there was typo. But this does not solve the problem. If you run the code, you will probably crash on first line using `x.name` as it is not know at that place and if you somehow bind it to fan_details class, it will still not print different addresses, as they are stored as so called class attributes and not as instance ones. – Jan Vlcinsky Apr 30 '14 at 22:38
0

List is mutable object so it won't allocate new memory... Copy x ... If iterating ... If not then use different variable...

Suggestion... Please provide complete code (relevant to question )