For list unless empty in python

Question:

I’ve been writing a lot of constructs like this the past couple of days:

list = get_list()
if list:
    for i in list:
        pass # do something with the list
else:
    pass # do something if the list was empty

Lot of junk and I assign the list to a real variable (keeping it in memory longer than needed). Python has simplified a lot of my code up til now… Is there a easy way to do this?

(My understanding is that the else in the for: else: construct always triggers after it has looped, empty or not – so not what I want)

Asked By: Oli

||

Answers:

def do_something_with_maybe_list(maybe_list):
    if maybe_list:
        for x in list:
            do_something(x)
    else:
        do_something_else()

do_something_with_maybe_list(get_list())

You could even extract the actions to be done:

def do_something_with_maybe_list(maybe_list, process_item, none_action):
    if maybe_list:
        for x in list:
            process_item(x)
    else:
        none_action()

do_something_with_maybe_list(get_list(), do_something, do_something_else)
do_something_with_maybe_list(get_otherlist(), do_other, do_still_other)

Edit from Oli: Or go one further:

def do_something_with_maybe_list(maybe_list, process_item, none_action):
    if maybe_list:
        return process_list(maybe_list)
    return none_action()

do_something_with_maybe_list(get_list(), do_something, do_something_else)
do_something_with_maybe_list(get_otherlist(), do_other, do_still_other)
Answered By: Jonathan Feinberg

Slighty more terse is:

for i in my_list:
    # got a list
if not my_list:
    # not a list

assuming you are not changing the length of the list in the loop.

Edit from Oli: To compensate my worries of memory use, it would want withing:

with get_list() as my_list:
    for i in my_list:
        # got a list
    if not my_list:
        # not a list

But yes, that’s quite a simple way around the issue.

Answered By: Kenan Banks

Use a list comprehension:

def do_something(x):
  return x**2

list = []
result = [do_something(x) for x in list if list]
print result        # []

list = [1, 2, 3]
result = [do_something(x) for x in list if list]
print result       # [1, 4, 9]
Answered By: user35288

If your actions are different, I would do:

list_ = get_list() # underscore to keep built-in list
if not list_:
    # do something
for i in list_: #
    # do something for each item

If your actions are similar, this is more beautiful:

for i in list_ or [None]:
   # do something for list item or None

or, if you might have None as a list element,

for i in list_ or [...]:
   # do something for list item or built-in constant Ellipsis
Answered By: ilya n.

Based on the other answers, I think the cleanest solutions are

#Handles None return from get_list
for item in get_list() or []: 
    pass #do something

or the comprehension equiv

result = [item*item for item in get_list() or []]
Answered By: Tom Leys

I think your way is ok in general case, but you may consider this approach:

def do_something(item):
   pass # do something with the list

def action_when_empty():
   pass # do something if the list was empty

# and here goes your example
yourlist = get_list() or []
another_list = [do_something(x) for x in yourlist] or action_when_empty()
Answered By: Jiri
i = None
for i in get_list():
    pass # do something with the list
else:
    if i is None:
        pass # do something if the list was empty

Does that help? Yes I know we are two years away from the need 🙂

Answered By: Laserwhit
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.