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)
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)
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 with
ing:
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.
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]
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
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 []]
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()
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 🙂
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)
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)
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 with
ing:
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.
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]
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
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 []]
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()
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 🙂