Reputation: 61
I have a list. It contains values of different types. For instance,
[1, 2, 3, 'a', False, 0, 5, 0, 3]
The task is to move all of the zeros to the end of the list. It should look like this
[1, 2, 3, 'a', False, 5, 3, 0, 0]
How can I distinguish the boolean value False
from 0
? I'm trying to analyze the values one by one comparing them with 0
.
However, Python does not see any difference between 0
and False
and in the end I have something like this below
[1, 2, 3, 'a', 5, 3, 0, 0, 0]
Upvotes: 2
Views: 2804
Reputation:
You can do something like this in just single loop :
first collect all int values which are non-zero in one list and all zero in second list , at last extend the list:
list_1=[1,2,3,'a', False,0,5,0,3]
all_zero=[]
all_int=[]
for i in list_1:
if i!=0:
all_int.append(i)
else:
all_zero.append(i)
all_int.extend(all_zero)
print(all_int)
output:
[1, 2, 3, 'a', 5, 3, False, 0, 0]
Upvotes: 0
Reputation: 26315
For this problem, type checking is a good idea. You could check if the current element is 0
and its not of type bool
, and remove that element and add it to end of the list:
lst = [1,2,3,'a', False,0,5,0,3]
for i, x in enumerate(lst):
if x == 0 and not isinstance(x, bool):
lst.append(lst.pop(i))
print(lst)
Which Outputs what you want:
[1, 2, 3, 'a', False, 5, 3, 0, 0]
Or you could make two lists, one with zeroes, and one with non-zeroes, and add them together. For the list of non-zeroes, the elements must not be 0
, but can be of type bool
, since False
does not get moved to the end. However, for the list of zeroes, the elements must be 0
, but not of type bool
, since we don't want to move False
to the end.
Here are some examples below:
1. Using list comprehensions
non_zeroes = [x for x in lst if x != 0 or isinstance(x, bool)]
zeroes = [x for x in lst if x == 0 and not isinstance(x, bool)]
print(non_zeroes + zeroes)
# [1, 2, 3, 'a', False, 5, 3, 0, 0]
2. Using filter()
:
non_zeroes = list(filter(lambda x: x != 0 or isinstance(x, bool), lst))
zeroes = list(filter(lambda x: x == 0 and not isinstance(x, bool), lst))
print(non_zeroes + zeroes)
# [1, 2, 3, 'a', False, 5, 3, 0, 0]
Note: For the type checking, we can use type()
or isinstance()
here. You can choose either.
Upvotes: 1
Reputation: 11
Python has a built-in function type() which returns the "type" object of the parameter.
You can simply do:
array = [1,2,3,'a', False,0,5,0,3] #Initial Array
for element in range(len(array)): #Iterating indexes in the array
if type(array[element])==type(1) and array[element] == 0: #If the type of the element is an Integer AND If element is equal to 0
e = array.pop(element) #Remove the element from its current position
array.append(e) #Adding the element at the end of the array
element -= 1 #Decrementing current index
print(array)
Upvotes: 1
Reputation: 110218
In Python, due to historic and not breaking compatibility reasons, bool is a subclass of "int" and False and true just evaluate to 0 and 1.
You can use a custom key function that checks, besides equality to zero, the type of the element. And then, since you want only 0s at the end, use the "0 and 1" equivalence of bool on your favor - elements that fail the boolean expression in the function are evaluated to "0" and placed before all the rest.
mylist.sort(key=lambda value: value == 0 and not isinstance(value, bool))
Order on the remaining elements, for which the key is "False" is guarranteed to be preserved: https://docs.python.org/3/howto/sorting.html#sort-stability-and-complex-sorts (Thanks to Patrick Haugh)
Upvotes: 3
Reputation: 71451
You can filter the list from zeroes and add a list with the number of zeroes found to the end of the filtered list:
s = [1,2,3,'a', False,0,5,0,3]
new_s = [i for i in s if isinstance(i, int) and i or isinstance(i, bool)]+[0]*s.count(0)
Output:
[1, 2, 3, False, 5, 3, 0, 0, 0]
Upvotes: 1