get list if contains non zero element - python

I have a list.
l1 = [0, 0, 2, 0]
l2 = [0, 0, 0, 0]
I want to print list if list contains non zero element in it.
Output:
If one one list passed, then only list with non zero element will get printed. In example above only l1 will get printed.
[0, 0, 2, 0]
I want to know how efficiently it can be done. Thanks !

Use any on your lists:
for lst in (l1, l2):
if any(lst):
print(lst)
You can also use all:
for lst in (l1, l2):
if all(x != 0 for x in lst):
print(lst)
I hope this helps.

You can use the built-in function any():
From Python's documentation:
any(iterable)
Return True if any element of the iterable is true. If
the iterable is empty, return False
Here's a code:
for l in [l1,l2, ..., ln]:
if any(l):
print(l)

You can try this:
lists = [[0, 0, 0, 0],[0, 0, 2, 0]]
for l in lists:
if set(l)=={0}:
pass
else:
print l

You can use the built-in any to test if the list contains at least one non-Falsy/non-zero element.
Zero is falsy, in fact the only falsy number:
>>> bool(0)
False
So you can easily do:
for lst in (l1, l2):
if any(lst):
print(lst)
This would provide correct results as long as your lists contains only numericals and you're not willing to make an expcetion of non numericals.

Answered in the comments, but I'll post it as an answer:
for l in filter(any, (l1, l2)):
print(l)
The combination of filter and any makes it so the print only executes for lists with non-zero elements. any returns False as soon as the first non-zero (or truthy) value is encountered. For integers, 0 is the only i for which bool(i) is falsey.

Related

How does sorted() work for lists inside of lists

I am confused on how lists inside lists get sorted.
L = [[1,1,1],[0,9,0],[2,1,1]]
sorted(L) returns [[0, 9, 0], [1, 1, 1], [2, 1, 1]]
This means that it is not based off sum as 0+9+0 is larger than both of the other ones.
No it is based on all the elements of the iterator starting from the first element of the iterator
sorted(L,key=lambda x:(x[0],x[1],x[2]) #==sorted(L)
In case you need by sum
sorted(L,key=sum)
A more simplified version of above code to understand the key argument further
print(sorted(L,key=lambda x: x[0]+x[1]+x[2]))
Built-in sorted considers each element of an iterable in turn. So, for example, [0, 9, 0] appears first because 0 < 1 and 0 < 2.
To help gain intuition, you can test a few examples:
[0,9,0] < [1,1,1] # True
[0,9,0] < [0,8,0] # False
[1,1,1] < [2,1,1] # True
So sorted works consistently with how comparison operators are defined. Sequence objects in Python usually support lexicographic comparison. To sort by the sum of each list, you need to feed a function to the key argument, in this case built-in sum:
res = sorted(L, key=sum)

How to check if a sequence of INTs are in a list and remove them in Python

I have a list with integers, in which every second int is zero (0), like this:
mylist = [1,0,2,0,3,0,4,0]
I can only check single positions like so:
for i in range(0, len(mylist)):
if i in mylist:
#do something here
I am trying to check for two positions at every loop, so if the loop finds for example "2, 0" in mylist, it will be able to remove those two ints.
Any suggestion will be appreciated.
Since the values between the 0s are unique, you can simply use list.index to find the target value and then use del to delete this value and the next one from the list:
>>> my_list = [1,0,2,0,3,0,4,0]
>>> my_index = my_list.index(3)
>>> del my_list[my_index:my_index+2]
>>> my_list
[1, 0, 2, 0, 4, 0]
Here is an example if you wanna remove the sequence (2,0), taking into account flatten method mentionned below:
from itertools import izip, chain
>>> list(chain(*[[u,v] for u,v in izip(*[iter(mylist)]*2) if (u,v)!=(2,0)]))
[1, 0, 3, 0, 4, 0]
All credits goes to:
Creating a python dictionary from a line of text

How to remove list of list at specific index

I'm trying to figure out how to delete an entire list at a specific index if the first element on the inside list meets a certain condition. Below I've shown an example of what I want done but when I run the code I'm getting a list index out of range error in python. If the list[i][0] meets a certain condition I want that entire list delete from the overall list.
list = [[0, 0, 0], [1, 1, 1], [2, 2, 2]]
for i in range(0, len(list)):
if list[i][0] == 0:
del list[i]
return list
Below I've shown a picture of what happens when I run the sample code in IDLE, the first time I run the loop it gives an error but the second time I run the code (copy and pasted both times) it doesn't and it does what I'm asking.
Weird Python Error
Deleting an element from the middle of a list moves everything down, breaking indexing. You need to either remove elements from the end:
for i in range(len(lst)-1, -1, -1):
if lst[i][0] == 0:
del lst[i]
or build a new list and assign it back to the variable, which would also be much more efficient:
lst = [x for x in lst if x[0] != 0]
Try changing your code to this, and 'list' is not a good variable name since it's already a builtin function:
my_list = [[0, 0, 0], [1, 1, 1], [2, 2, 2]]
my_list = [l for l in list if l[0] != 0]
print(my_list)
Usually it's not a good idea to remove elements from list while iterating through it like that because the first time you remove an element the list will no longer be the same length.
1) Create completely new list which will contain elements you want to keep:
listname = [element for element in listname if element[0] != 0]
2) Modify the list you already have (you can do this since lists are mutable):
listname[:] = [element for element in listname if element[0] != 0]
I would recommend using the second approach in case you have references to the same list somewhere else in you program.
Also try not to name your variables list, it's really not a good practice and it probably is not possible since it's keyword.
First, do not ever call your variables list.
Second, a while loop may be a slightly better solution:
stop = range(len(mylist))
i = 0
while i < stop:
if mylist[i][0] == 0:
del mylist[i]
stop -= 1
else:
i += 1
Third, a list comprehension is event better:
[item for item in mylist if item[0] != 0]
It's always bad idea to remove elements from a container while you are iterating over it.
A better approach would be to instead of removing bad elements from the list, copy good ones to a new list:
original = [[0, 0, 0], [1, 1, 1], [2, 2, 2]]
new_list = []
for l in original:
if list[0] != 0:
new_list.append(l)
return new_list
And by the way, "list" is a python keyword and can't be used as variable name.
Or better, use the built-in filter function:
return filter(lambda l : l[0] != 0, original)

Mapping a list into a reference list

I am trying to make this as clear as I can. Please let me know if I should clarify anything.
I have a long list of variables in a list in the following format -
L = ["Fruit", "Transportation", "Housing", "Food", "Education"]
I would like to map a shorter list into it. The shorter list does not have each but only some of the variables in the long list. For instance -
S = ["Fruit", "Food"]
What I am interested in obtaining is the binary values of the short list while it maps into the L list.
With S as an example, it should be:
S = [1, 0, 0, 1, 0]
I tried map(S, L) but clearly a list is not callable.
TypeError: 'list' object is not callable
What would be a good way to do this? Thank you!!
By using a list comprehension that takes every value in L and if it is contained inside S it returns a value of 1, and, if not, it returns a value of 0:
m = [1 if subval in S else 0 for subval in L]
the result is:
[1, 0, 0, 1, 0]
Try this:
[int(x in S) for x in L]
You can use python's list comprehension as follow:
ans=[1 if x in S else 0 for x in L]
I tried map(S, L) but clearly a list is not callable.
But its methods are:
>>> map(S.count, L)
[1, 0, 0, 1, 0]
(This one assumes there are no duplicates in S. If that's not the case, you could for example use map(list(set(S)).count, L) instead.)

Unexpected behavior of if/else in list comprehension

Why do I get the following behavior? I expect the result to be just 1.
In [77]: a = 1
In [78]: [a if a else s for s in [0, 1,0]]
Out[78]: [1, 1, 1]
Since a is not empty the value in the list should be a only.
Here else should only be executed when a is None.
EDIT: I want to insert a in the list if a is not None, else insert s in the list.
That's normal behavior. You're iterating through a list that contains three numbers. if a is always true. So, a if a is executed three times. That's why you get three a's added to the list.
Regarding your latest edit:
I want to insert a in the list if a is not None, else insert s in the list.
Okay, then you do this:
res=[]
if a:
res.append(a)
else:
for s in [0,1,0]:
res.append(s)
a if a else s evaluates to a if a is truthy. a never changes, so no matter what you iterate through in the list comprehension, you will get the same thing: a list of as as long as what you are iterating through.
Maybe you want this?
[a] if a else [0, 1, 0]
This expression will evaluate to a list with a in it if a is truthy, otherwise it'll evaluate to the list you provided.
There's no need to put the else inside the brackets.
>>> a = 1
>>> [a] if a else [0, 1, 0]
[1]
>>> a = None
>>> [a] if a else [0, 1, 0]
[0, 1, 0]

Categories