1

Very beginner question but it is driving me mad. sample1, sample2 etc. are Pygame.mixer.sound objects.

sample_list = []
sample_list.append(sample1)
sample_list.append(sample2)
sample_list.append(sample3)

Is fine, but I want to do that using a for style loop, e.g.

for j in range(1, 3, 1):
    sample_list.append(sample + j)

But that is trying to add a number to a sound object so isn't right. I can add the equivalent string by;

for j in range(1, 3, 1):
    sample_list.append("sample" + str(j))

But that doesn't refer to the objects I want, just adds those strings. I've tried must permutations of syntax I can think of but it is still alluding me! Thanks.

2
  • @PicklishDoorknob: You actually can get a variable by name, Commented Nov 17, 2012 at 20:46
  • @PicklishDoorknob: Martijn gave the answer for looking in the current scope. Then there is also getattr(obj, name) when you want to get an attribute on an object by string name. Commented Nov 17, 2012 at 20:48

4 Answers 4

3

Don't store the objects in variables in the first place; store them directly into a list, and then you will be able to index them by integer.

If the integer identifiers are sparse, use a dict indexed by integer.

Sign up to request clarification or add additional context in comments.

Comments

2

I would recommend storing these in a dict to begin with. It is almost the same effect for you to reference by a name, but without the explicit object symbol for each:

samples = {
    "sample1": Sample(),
    "sample2": Sample()
}
samples['sample3'] = Sample()

This is the preferred approach when you have a dynamic number of objects you are creating and want to be able to grab them by a name later. You can store 100's of these in your dict without cluttering up your namespace.

And later if you are trying to apply this to your loop, you can reference the string names:

for i in xrange(1,4):
    sample_list.append(samples["sample" + str(i)])

As a side note another way to get attributes by name when they live on some object is to use getattr. Assume you have this:

class Sampler(object):
    pass

sampler = Sampler()
sampler.sample1 = Sample()
sampler.sample2 = Sample()
sampler.sample3 = Sample()

You can then reference by name via: getattr(sampler, "sample1")

Note: As mentioned in comments by @Marcin, if you don't care about having a string identifier to be able to look up your items, and they are just purely sequential by number, you can use this same approach but with a list. It depends on your needs.

It is possible you might want to end up doing something like:

samples = {
    "bang1": Sample(),
    "bang2": Sample(),
    "bang3": Sample(),
    "shot1": Sample(),
    "shot2": Sample(),
    ...
}

... Which would then allow you to look up sequential subsets of those sounds.

2 Comments

Right, but if the identifiers only differ by number, why bother with a dict?
Because I don't want to assume that will always be the case. Yes a list would be much easier if you don't need to reference a "key" name for these items. If the OP doesn't care about a string identifier, a list will suffice.
0

You can dynamically load variables from the locals() mapping:

for j in range(1, 4):
    sample_list.append(locals()["sample" + str(j)])

Generally, you want to avoid such tricks; find other ways to store your sample variables, in a mapping or a list for example.

1 Comment

Gah I was typing that out! :-) I was also going to recommend that the OP keep these sample objects in a dict in the first place.
-2

Looks like the wrong approach, but nevertheless.

sample_list = [eval('sample' + str(i)) for i in range(1, 4)]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.