4

I think there should be a question like this already, but I haven't found it. It could be because I don't know the exact concepts/words about what I'm looking for, but here is the example:

I have this code:

group_1 = ['Hello', 'world', '!']
group_2 = [1,23,4,2,5,2]
group_3 = ['A', 'K', 'L']

all_groups = [group_1, group_2, group_3]
for i in all_groups:
    print(i, ':', len(i))

It gives this output:

['Hello', 'world', '!'] : 3
[1, 23, 4, 2, 5, 2] : 6
['A', 'K', 'L'] : 3

And this is the expected output:

'group_1' : 3
'group_2' : 6
'group_3' : 3

As you can see, I'm trying to print the names of the callable objects group_1, group_2, and group_3. Any suggestions?

BrokenBenchmark
  • 18,126
  • 7
  • 21
  • 33
Chris
  • 2,019
  • 5
  • 22
  • 67
  • Check out https://stackoverflow.com/questions/18425225/getting-the-name-of-a-variable-as-a-string – Joseph Camacho May 27 '22 at 23:57
  • In general, when a program can know information about its own structure or variable names, it's called ["reflection"](https://en.wikipedia.org/wiki/Reflective_programming). Reflection should generally be avoided, but can be useful in some cases. As others are saying, you may want to restructure your data a little to have those names (e.g. `group_1`) be part of the actual data and not just variable names. – nullromo May 27 '22 at 23:57
  • 1
    First, those are not "callable objects". They are just lists. Second, an object does not know its own names. What `all_groups` contains is a list of three references to lists. `group_1` also happens to contains a reference to one of the lists. `all_groups` has no idea that some other name is also bound to those objects. If you NEED the names, then store them in a dictionary, not a list. – Tim Roberts May 27 '22 at 23:57
  • @JosephCamacho thanks! But that answer doesn't work, it gives me a syntax error. – Chris May 28 '22 at 00:59
  • Objects don't know what names they have; they can have any number of names (or no names); and the objects in your example **are not "callable"**. This question is based on multiple misconceptions and does not make sense as asked. It also clearly doesn't have anything to do with `pandas`. – Karl Knechtel May 28 '22 at 01:07
  • It would be better to say, objects *don't* "have names"; they simply are named (sometimes). It is the *names* which "have" the *objects* (or *values*), in the most meaningful sense of "have". – Karl Knechtel May 28 '22 at 01:14

3 Answers3

5

Restructure your code so that it uses a dictionary to store the group names.

I would not recommend approaches that use anything related to reflection, the inspect module, or locals(), as described (or linked to) in the comments. The names of the variables in all_groups list aren't preserved when you add them to all_groups; even if they were, accessing these names would likely be more complex than just using a dictionary:

data = {
    'group_1': ['Hello', 'world', '!'],
    'group_2': [1,23,4,2,5,2],
    'group_3': ['A', 'K', 'L']
}

for k, v in data.items():
    print(k, ':', len(v))

This outputs:

group_1 : 3
group_2 : 6
group_3 : 3
BrokenBenchmark
  • 18,126
  • 7
  • 21
  • 33
  • Could you elaborate please why would you not recommend those approaches? I have never heard about those – Chris May 28 '22 at 00:51
  • There's two reasons. The first is fragility -- if you add new variables into the script, those might get picked up by `locals()`, and then will error when you call `len()` on it. The second is readability; the approach I've described is pretty readable (or at least, I would like to think that it's readable). Throwing extra modules or reflection at the problem is likely going to be more difficult for someone else to understand than just using a dictionary. Long story short, there's a reason why you've never heard of these approaches. – BrokenBenchmark May 28 '22 at 01:34
1

The following code:

all_groups = [group_1, group_2, group_3]
for i in all_groups:
    print(i, ':', len(i))

Takes the values of those three existing variables group_1, group_2 and group_3 and puts them into a list with three items.

When you iterate over that list and print the items, you get their values, not their names (which is a concept reserved for humans, because we cannot understand code otherwise).

If you want to store their names, you store them in a dictionary:

all_groups = {
  'group_1': group_1,
  'group_2': group_2,
  'group_3': group_3
}

And then print their name using:

for k,v in all_groups.items():
    print(k, ':', len(v))
Daniel Trugman
  • 8,186
  • 20
  • 41
1

You can just use globals(), because why not:

group_1 = ['Hello', 'world', '!']
group_2 = [1,23,4,2,5,2]
group_3 = ['A', 'K', 'L']

all_groups = ['group_1', 'group_2', 'group_3']

for grp in all_groups:
    print(locals()['grp'], ':', len(globals()[grp]))
rv.kvetch
  • 9,940
  • 3
  • 24
  • 53