Hound
Hound

Reputation: 972

List Comprehension Example

How could I do the below code with a list comprehension. I have been looking at these examples, but I can't figure it out :|

Python: Removing list element while iterating over list

list_dicts = [{'site': 'living', 'status': 'ready' }, {'site': 'keg', 
'status': 'ready' }, {'site': 'box', 'status': 'ready' }, {'site': 'wine', 
'status': 'not_ready' }]

def call_some_func(m_site_dict):
     print "I executed the 'call_something_function'"

for site in list_dicts[:]:
    if site['status'] == 'ready':
        call_some_func(site)
        list_dicts.remove(site)

Upvotes: 1

Views: 215

Answers (1)

AChampion
AChampion

Reputation: 30258

It is not a great idea to replace this for loop because you are making a function call with side effects (currently printing). You can use an else clause to construct a new list, which would be more performant (O(1) for append() vs O(n) for del) e.g.:

In []:
new_list_dicts = []
for site in list_dicts:
    if site['status'] == 'ready':
        call_some_func(site)
    else:
        new_list_dicts.append(site)
new_list_dicts

Out[]:
I executed the 'call_something_function'
I executed the 'call_something_function'
I executed the 'call_something_function'

[{'site': 'wine', 'status': 'not_ready'}]

Just as a demonstration (but very bad form) you can do this as a list comprehension but it relies on short-circuiting and the fact the call_some_func() returns None which is considered False:

In []:
[site for site in list_dicts if site['status'] == 'ready' and 
 call_some_func(site) or site['status'] != 'ready']

Out[]:
I executed the 'call_something_function'
I executed the 'call_something_function'
I executed the 'call_something_function'

[{'site': 'wine', 'status': 'not_ready'}]

Upvotes: 1

Related Questions