Alex
Alex

Reputation: 2402

Python list.remove() not working

I am including a python file commands.py using import commands

The file is as follows:

import datetime

def what_time_is_it():
    today = datetime.date.today()
    return(str(today))

def list_commands():
    all_commands = ('list_commands', 'what time is it')
    return(all_commands)

I would like the main script to list the functions in commands.py, so I'm using dir(commands) which gives the output:

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'datetime', 'list_commands', 'what_time_is_it']

I then tried to use regular expressions to remove the items that include '__' as follows:

commands_list = dir(commands)
for com in commands_list:
   if re.match('__.+__', com):
      commands_list.remove(com)
   else:
      pass

This doesn't work. If I try to do it without the for loop or the regular expressions, it claims that the entry (which I had just copied and pasted from print(list) is not in the list.

As a secondary question, can I get dir to only list the functions, rather than 'datetime' as well?

Upvotes: 2

Views: 5920

Answers (4)

ettanany
ettanany

Reputation: 19806

Using list comprehension, try this:

[item for item in my_list if '__' not in (item[:2], item[-2:])]

Output:

>>> [item for item in my_list if '__' not in (item[:2], item[-2:])]
['datetime', 'list_commands', 'what_time_is_it']

The same result can be achieved using filter():

filter(lambda item: '__' not in (item[:2], item[-2:]), my_list)  # list(filter(...)) for Python 3

Upvotes: 2

Zach Gates
Zach Gates

Reputation: 4130

You can filter the list:

commands_list = filter(lambda cmd: not re.match('__.+__', cmd), dir(commands))

This filters out all items that do not match the regex.

Upvotes: 0

Francisco
Francisco

Reputation: 11476

You can't modify a list while you're iterating it, use a list comprehension instead:

commands_list = dir(commands)
commands_list = [com for com in commands_list if not re.match('__.+__', com)]

As your second question, you can use callable to check if a variable is callable or not.

Upvotes: 8

acushner
acushner

Reputation: 9946

i would just use a list comp here:

commands_list = [cmd for cmd in commands_list if not (cmd.startswith('__') and cmd.endswith('__'))]

Upvotes: 4

Related Questions