In python, What is the most preferred (pythonic) way to do the following:
You are given a list. If the list is not empty, all items in the list are guaranteed to be strings. Each item in the list is either the empty string, or is guaranteed to return True if isdigit() is called on the item.
Starting with such a list, what is the most elegant way to end up with a list such that it has all items from the original list, except for the empty strings?
Using filter() with the default identity function (None):
newlist = filter(None, origlist)
alternatively, a list comprehension:
newlist = [el for el in origlist if el]
Related
What is the most efficient way to check whether a set string is present in all of three given lists, and if so, set itemInAllLists to True?
Below is the general idea of what I'm trying to achieve.
item = 'test-element'
list_a = ['a','random','test-element']
list_b = ['light','apple','table']
list_c = ['car','field','test-element','chair']
itemInAllLists = False
if item in [list_a] and item in [list_b] and item in [list_c]:
itemInAllLists = True
Check if string present in multiple lists (Python)
Have a look at the all built-in for Python. It will return True if all elements of an iterable is true.
If you put all your lists in a combined list, you can do list comprehension to check each list.
all(item in all_lists for all_lists in [list_a, list_b, list_c])
As deceze mentions, you don't have to do it this way. What you are doing works as well and might be easier to read. Using all or any might be better suited for more lists or when you create them dynamically.
For your code to work, you just have to remove the brackets so the syntax is correct:
if item in list_a and item in list_b and item in list_c:
pass
I'm trying to convert this for loop into "list comprehension" format if possible:
This loop adds 0 into two dimensional list
test_list = [['string1'],['string2'],['string3']]
for i in range(len(test_list)):
test_list[i].insert(1, 0)
output:
test_list = [['string1',0],['string2',0],['string3',0]]
I've tried this but for some reason it doesn't work.
test_list = [test_list[i].insert(1, 0) for i in range(len(test_list))]
It doesn't work, because list.insert() modifies the list in-place and returns None, so you will end up with a list of Nones which are return values from all .insert()s.
List comprehension format is not adequate for what you want, because it is designed to create new lists, and you seem to want to modify the list in-place. If you want to create new lists instead, you can use this:
test_list = [sublist + [0] for sublist in test_list]
this works because the + operator on lists creates and returns a new list.
Is your question "what's the reason?"
The line
test_list = [test_list[i].insert(1, 0) for i in range(len(test_list))]
means "make a list of the return values of this expression".
The return value of the expression [].insert() is None. test_list will be set to a list of Nones.
If I have this list,
list01 = ['GAGGT','TCCGT','ABECF']
I want to make each element in the list to split, but still remain in the same box of list.
Like this:
listalt = [['G','A','G','G','T'],['T','C','C','G','T'],['A','B','E','C','F']]
listalt = [list(i) for i in list01]
This is a list comprehension, and uses the fact that list can take an iterable (like a string) and turn it into a list
You can use this :
final_list=[]
for item in list01:
final_list.append(list(item))
print(final_list)
which is same as :
print([list(item) for item in list01])
I have a list of record instances returned by SQLAlchemy.
While the instances have many attributes, I want a new list with only one of the attributes. The java coder in me says:
my_records = query.all()
names = []
for my_record in my_records:
names.append(my_record.name)
...which works, of course. But What's the Pythonic answer? I know there a one-liner that includes these 4 lines into 1, but finding it is like googling for "for".
You are looking for what is called a list comprehension:
names = [my_record.name for my_record in query.all()]
The above is a concise equivalent to the for-loop in your example.
In addition, you should be aware that there are dict comprehensions:
{key:val for key, val in iterable}
as well as set comprehensions:
{item for item in iterable}
which will construct new dictionaries and sets respectively.
Lastly, all of these constructs allow you to add an optional condition to be tested for each item:
[item for item in iterable if condition]
{key:val for key, val in iterable if condition}
{item for item in iterable if condition}
This is useful if you want to filter the items from the iterable by the condition.
You want to do a list comprehension:
result = [my_record['name'] for my_record in query.all()]
Alternatively to list comprehension you can use operator.attrgetter and map:
map(operator.attrgetter('name'), query.all())
(But the list comprehension variant is easier to read IMO.)
I have a list of strings, and calling a function on each string which returns a string. The thing I want is to update the string in the list. How can I do that?
for i in list:
func(i)
The function func() returns a string. i want to update the list with this string. How can it be done?
If you need to update your list in place (not create a new list to replace it), you'll need to get indexes that corresponds to each item you get from your loop. The easiest way to do that is to use the built-in enumerate function:
for index, item in enumerate(lst):
lst[index] = func(item)
You can reconstruct the list with list comprehension like this
list_of_strings = [func(str_obj) for str_obj in list_of_strings]
Or, you can use the builtin map function like this
list_of_strings = map(func, list_of_strings)
Note : If you are using Python 3.x, then you need to convert the map object to a list, explicitly, like this
list_of_strings = list(map(func, list_of_strings))
Note 1: You don't have to worry about the old list and its memory. When you make the variable list_of_strings refer a new list by assigning to it, the reference count of the old list reduces by 1. And when the reference count drops to 0, it will be automatically garbage collected.
First, don't call your lists list (that's the built-in list constructor).
The most Pythonic way of doing what you want is a list comprehension:
lst = [func(i) for i in lst]
or you can create a new list:
lst2 = []
for i in lst:
lst2.append(func(i))
and you can even mutate the list in place
for n, i in enumerate(lst):
lst[n] = func(i)
Note: most programmers will be confused by calling the list item i in the loop above since i is normally used as a loop index counter, I'm just using it here for consistency.
You should get used to the first version though, it's much easier to understand when you come back to the code six months from now.
Later you might also want to use a generator...
g = (func(i) for i in lst)
lst = list(g)
You can use map() to do that.
map(func, list)