Author Topic: python/libtcod tutorial, need help w/ list comprehensions  (Read 6280 times)

Namtaru

  • Newcomer
  • Posts: 2
  • Karma: +0/-0
    • View Profile
python/libtcod tutorial, need help w/ list comprehensions
« on: January 29, 2013, 11:47:33 PM »
I am on part 2 of the tutorial and I am trying to wrap my head around list comprehensions. I understand most of it, what is stopping me up is this part:
Quote
One very important piece of advice: in list comprehensions, always call the constructor of the objects you're creating, like we did with Tile(False). If we had tried to first create an unblocked tile like floor = Tile(False) and then in the list comprehension just refer to that same floor, we'd get all sorts of weird bugs! This is a common rookie (and veteran!) mistake in Python. That's because all elements in the list would point to the exact same Tile (the one you defined as floor), not copies of it. Changing a property of one element would appear to change it in other elements as well! Calling the constructor for every element ensures that each is a distinct instance.

Can someone reword this for me? Here are the code snippets so no one has to go to the wiki:
Code: [Select]
class Tile:
    #a tile of the map and its properties
    def __init__(self, blocked, block_sight = None):
        self.blocked = blocked
 
        #by default, if a tile is blocked, it also blocks sight
        if block_sight is None: block_sight = blocked
        self.block_sight = block_sight

Code: [Select]
def make_map():
    global map
 
    #fill map with "unblocked" tiles
    map = [[ Tile(False)
        for y in range(MAP_HEIGHT) ]
            for x in range(MAP_WIDTH) ]

Thank you for your time.

mughinn

  • Newcomer
  • Posts: 39
  • Karma: +0/-0
    • View Profile
Re: python/libtcod tutorial, need help w/ list comprehensions
« Reply #1 on: January 30, 2013, 01:20:49 AM »
If i understand right, it means that you should create a new instance of the class in the list comprehension, instead of creating one before and use the variable, else you end up referencing that same variable in the whole map.

I don't know if you will understand that, so i'll try another thing:

Imagine this

Code: [Select]
def make_map():
    global map
    floor = Tile(False)

    #fill map with "unblocked" tiles
    map = [[ floor
        for y in range(MAP_HEIGHT) ]
            for x in range(MAP_WIDTH) ]

in that code, you would have only ONE floor tile, referenced in the whole map, so if you drop an object to the floor, the object would appear everywhere, and if a monster walked around there (or the player for that matter) it would also appear in every tile

kraflab

  • Rogueliker
  • ***
  • Posts: 454
  • Karma: +0/-0
    • View Profile
    • kraflab.com
Re: python/libtcod tutorial, need help w/ list comprehensions
« Reply #2 on: January 30, 2013, 02:35:11 AM »
In that list is a set of references to objects, if I'm understanding your question right.

Let me word this in an extra way in case you didn't understand the guy above me either.  Imagine I have references to people, which I will dub names.  So I may have a list with people[]=[kraflab, mughinn, Namtaru].  If I wanted to fill a new list with people, I could erroneously just add a bunch of kraflab, such as people[]=[kraflab, kraflab, kraflab].  But then if I called people[0].height=5 I would also change people[1].height to 5, since they are referencing the same person.  Thus, I would want to create my list as people[]=[person(),person(),person()] (where person creates and returns a new unique person).

You can think of a reference as an internal handle or "name" for an individual object, except instead of a name like "mughinn" it will be a memory address.  When you create a new object, a reference gets created that points to a location in memory that was allocated to store that object.

Namtaru

  • Newcomer
  • Posts: 2
  • Karma: +0/-0
    • View Profile
Re: python/libtcod tutorial, need help w/ list comprehensions
« Reply #3 on: February 01, 2013, 05:56:52 AM »
Thank you for that it makes a lot more sense now. I kept going through the tutorial yesterday and today, and after coding more and reading this thread I got it finally. Certain concepts feel like a wall until they turn into just another step  :) Speaking of which I have a few questions about class components... but that's for another thread when I am not too falling asleep at the keyboard.

Thanks again guys