user2726268
user2726268

Reputation: 13

How do I use values from a tuple which is in a list of tuples as arguments for a function?

I'm trying to construct a simple tilemap thingy, as part of a larger project, and one of the solutions I came out with was to use a function like so:

def tile((value, X, Y)):
    if value == 1:
        pygame.draw.rect(screen, (0, 0, 0) (X, Y, 64, 64), 0)

The idea being that I set the level out as a list of tuples that contain a value which denotes the tile to be drawn there, and then the coordinates of that tile.

This, of course, doesn't work since you can't use a tuple as an argument.

My solution to this was to instead get the values out of the tuple in the list:

def tile(value, X, Y):
    if value == 1:
        pygame.draw.rect(screen, (0, 0, 0) (X, Y, 64, 64), 0)


level = [(1, 0, 0), (rest of list)]
tile(level[0[0]], level[0[1]], level[0[2]])

Which didn't work, and gave me

Traceback (most recent call last):
tile(level[0[0]], level[0[1]], level[0[2]])
TypeError: 'int' object has no attribute '__getitem__'

Does anyone have a workaround for this? Some way I can feed a tuple into a function as a series of arguments? Or am I just using a completely idiosyncratic method that won't ever work ever? I'm guessing this is just due to my blinding incompetence, although I would like to be told otherwise.

Python 2.7, pygame 1.9

Upvotes: 1

Views: 405

Answers (4)

ANortonsmith
ANortonsmith

Reputation: 146

The error that you are experiencing can be solved by changing this:

tile(level[0[0]], level[0[1]], level[0[2]])

To this:

tile(level[0][0], level[0][1], level[0][2])

You just had the brackets in the wrong place.

Another note: you can use a tuple as an argument to your function, which would look like this:

def tile((value, X, Y)):
    if value == 1:
        pygame.draw.rect(screen, (0, 0, 0), (X, Y, 64, 64), 0)

like you had in your original example. The rest of the code would then be simplified to this:

level = [(1, 0, 0), (rest of list)]
tile(level[0])

Upvotes: 1

Robᵩ
Robᵩ

Reputation: 168766

You certainly may pass a tuple into a function, and your fist attempt should have worked just fine:

def tile((value, X, Y)):
  if value == 1:
    pygame.draw.rect(screen, (0, 0, 0), (X, Y, 64, 64), 0) # Note typo: missing comma
level = [(1, 0, 0), (1, 10, 10), (1, 42, 99)]
for x in level:
    tile(x)

If you'd rather pass all the tiles simultaneously, you can do that, too. Just move the for loop into your function:

def tile(l):
  for value, X, Y in l:
    if value == 1:
      pygame.draw.rect(screen, (0, 0, 0), (X, Y, 64, 64), 0)
level = [(1, 0, 0), (1, 10, 10), (1, 42, 99)]
tile(level)

Finally, if you don't want to accept a tuple in your function, but do want to keep the data in a tuple, that is also an option. Use the * operator:

def tile(value, X, Y):
    if value == 1:
      pygame.draw.rect(screen, (0, 0, 0), (X, Y, 64, 64), 0)
level = [(1, 0, 0), (1, 10, 10), (1, 42, 99)]
for x in level:
    tile(*x)

Upvotes: 0

BrenBarn
BrenBarn

Reputation: 251518

You have an answer about the best way to handle your task, but the specific problem with the way you're doing it is that you need to do level[0][0] etc., not level[0[0]].

Upvotes: 1

Paul Evans
Paul Evans

Reputation: 27577

You need to unpack your tuple when you call like this:

tile(*level[0])

Upvotes: 0

Related Questions