Alex
Alex

Reputation: 61

How to distinguish bool from int

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

Answers (5)

user9158931
user9158931

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

RoadRunner
RoadRunner

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

Another Man
Another Man

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

jsbueno
jsbueno

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

Ajax1234
Ajax1234

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

Related Questions