lookiluke
lookiluke

Reputation: 71

How to get the name of lists for comparison purposes

This may sound a bit funny, but this is what am trying to do: I have two lists: myList1 and myList2. I am passing these lists to a function that will perform a specific task depending on which list it receives (i.e., based on the name of the list, not content).

def listProcessor(data):
    if data == 'myList1':
        perform task1
    else: #meaning data is myList2
        perform task 2

Is there a way in Python 3 to inquire of the name of a list (or a tuple, dictionary, etc.) and do a comparison like this? Obviously, the way I am doing it here isn't working since it's comparing the content of the list 'data' to the single string 'myList1', which isn't working! :-).

Upvotes: 2

Views: 55

Answers (2)

Burhan Khalid
Burhan Khalid

Reputation: 174700

There are a few ways to do this:

  1. You can create separate functions if what needs to be done for each list really is completely separate.

  2. You can update your function to either:

    1. Take two lists as an argument:

      def list_processor(list1=None, list2=None):
         if list1:
            # do stuff for list1
         if list2:
            # do stuff for list2
      
    2. You can add an extra flag, identifying what kind of action to be performed, and set a default as well:

      def list_processor(some_list=None, type_of_list=1):
          if type_of_list == 1:
              # do stuff with some_list as if it was list1
          if type_of_list == 2:
              # do stuff with some_list as if it was list2
      

You do not want to do what you initially proposed, for various reasons. One key reason is that in Python, what you may call variables in other languages are not "boxes to put stuff in" (as most textbooks refer to them).

In Python variables are actually just names that point to an object. The key thing is that multiple names can point to the same object; which will easily confuse your function if you rely on the lists "name".

Here is an example:

>>> a = [1,2,3]
>>> b = a
>>> b.append('hello')
>>> b is a
True
>>> b == a
True
>>> b
[1, 2, 3, 'hello']
>>> a
[1, 2, 3, 'hello']

In this example, both a and b are pointing to the same list object. What you do with a affects b.

Upvotes: 2

Adam Smith
Adam Smith

Reputation: 54223

So let's start with this: you really shouldn't do this. Data is just data in Python -- the identifier (e.g. the name you're using to talk about it) means nothing to the program logic itself. It's only meaningful to the programmer.

That said, there's ways to do what you're trying to do, and they're all the wrong thing to do. But they're possible, so let's talk about them.

globals() will give you a dictionary with keys of identifiers and values of, um, values, for all objects currently in the global scope. This means that you can do:

def list_processor(data):
    g = globals()
    data_name = next((k for k,v in g.items() if v is data))
    if data_name == 'myList1':
       ...  # do whatever you want here

Note, however, that you're looking through EVERYTHING in the global scope. First off, that's dumb since it's slow, and secondly, it's dumb because it's buggy. What if myList1 isn't being passed from the global scope? What if it's a local variable inside a function that never hits the global scope? Now your tricky hack fails.

The correct way to do this is to perform some sort of introspection on the argument being passed in as "data". For instance if myList1 always has 8 elements and myList2 always has 10:

def f_if_myList1(lst):
    """Do whatever we do if we pass myList1"""
    ...

def f_if_myList2(lst):
    """Do whatever we do if we pass myList2"""
    ...

def list_processor(data):
    if len(data) == 8:  # myList1!
        f_if_myList1(data)
    elif len(data) == 10:
        f_if_myList2(data)
    else:
        # not sure. raise ValueError()?

Upvotes: 1

Related Questions