In order to check if a given list is constituted only by 0 and 1 values, I tried to set up a function returning True when the list is binary, while it returns False when not:
My code
def is_binary(y):
for x in y:
if x in [2,3,4,5,6,7,8,9]:
return False
break
else:
return True
Itried it on the following list:
our_list=[1,0,0,0,1,1,0,0,0,0,1,0,1,0,1,1,1]
is_binary(our_list)
Output:
True
But it doesn't work when the variable is not binary.
Any help from your side will be appreciated.
You can also use a list comprehension with the result of checking if each element is binary, and use all to check that all elements are True.
Edit: as #Jonh Coleman suggested, instead of creating a list first and then applying all, we can take advantage of generators, which will only generate values as requested.
We then only need to generate elements until one of them evaluates False. all will take care of that by shortcircuiting and not continuing to request elements to the generator once one of them evaluates False. That will be both more memory and time efficient.
our_list=[1,0,0,0,1,1,0,2,0,0,1,0,1,0,1,1,1]
all(i in [0,1] for i in our_list)
False
def is_binary(arr):
for num in arr:
if num not in [0, 1]:
return False
return True
our_list=[1,0,0,0,1,1,0,0,0,0,1,0,1,0,1,1,1]
print(is_binary(our_list))
I found several mistakes in your code.
Firstly, your code stops when the return statement is executed. So your loop will only be executed once and return the result of the first element in the list.
Secondly, there are two binary numbers, and countless numbers that aren't binary. You're just checking if the numbers are in range(2, 10). When the number is not in that range, take 11 as example, since it is not in range(2, 10), it won't execute the return False statement.
Therefore, rather to check if the number is in countless un-binary numbers, check if the number is not binary.
I would turn around your logic.
def is_binary(y):
for x in y:
if x not in [0,1]:
return False
return True
The root of the problem is that you are returning the result at the first iteration round, because the return statement stops the execution of the function. This also makes your break statement redundant. See https://www.geeksforgeeks.org/python-return-statement/ for more info.
There are two use cases where your original solution works as expected and that is when the list length is one or the error is in the first item of the list y AND the "wrong" value is in the list [0,1, ...9] e.g. y=[0] or y=[1] or y=[1,0] returns True and y=[3] will return False. However, your solution fails, if y=['three'] or y=[13] or y=[0, 0, 3] because it returns True, though it should be False.
Related
Suppose we have this function:
def search(ls, e):
'''Assumes ls is a list.
Returns True if e is in ls, False otherwise.'''
for i in reversed(range(len(ls))):
if ls[i] == e:
return True
return False
I'm trying to get this function to search through ls starting from the end of the list instead of the beginning. Hence, I included reversed(), which reverses the list, ls.
However, what I'm specifically trying to do is search a list but instead of starting from the index of 0, starting from the index of -1. I don't think reversed() technically does this? If not, how could the function be modified to achieve my objective?
list1 = [1,2,3,4,5]
for i in reversed(range(len(list1))):
print(list1[i])
5
4
3
2
1
it does exactly what you want no?
l2 = [1,2,3,4,5]
for i in range(len(l2)):
print(l2[-i-1])
5
4
3
2
1
you could try something like:
for i in range(len(ls)):
if ls[(-1)*i] == e:
return True
return False
It should start at the back of the list and move forward.
I would actually use enumerate() to do the heavy lifting for you. Using print statements instead of return you can see how it is working better. Basically it creates a physical location index, 0 through the length of the list and allows you to iterate through both the values and the indexes. We do not need the indexes for this, but you have both.
x = [1,2,3,4,5]
for index, value in enumerate(reversed(x)):
if value== 2:
print("TRUE")
else:
print("FALSE")
This first reverses the list, creates enumerated indices and values, assigns the indices iteratively to index and each value (which can be anything a string, a float, another list)to the variable value and in the if else statement compares it to the value (which would be s in your function)
The output is:
FALSE
FALSE
FALSE
TRUE
FALSE
You can see it counted backwards toward 1. I makes seeing what is happening more explicit and allows you to use both the values and the index values of the reversed list without having to slice the original list and keep track of direction.
I have tried to create a function helping me to specify if my list "inc" is a list composed of increasing numbers. In the end, if I have a list of [1,2,3], I am expecting output as True and False when I have a list like [1,2,1]. With the following code, I get not the expected output which should be True.
inc=[1, 2, 3]
def increase(inc):
result = True
for i in range(0, len(inc)-1):
if inc[i] > inc[i-1]:
return result
else:
return False
print(increase(inc))
output=False
How about using sorted() function that returns a sorted list?
inc=[1, 2, 3] # try swapping items in the list
if sorted(inc) == inc:
print(True)
else:
print(False)
There are a few problems here. It returns False because lst[-1] is indeed bigger than lst[0]; you should start the range from 1.
In addition, it should return True only if the condition is True for all the iterations, not right after the first iteration.
write a function that takes, as an argument, a list called aList. It returns a Boolean True if the list contains each of the integers between 1 and 6 exactly once, and False otherwise.
This is homework and I thought I had it right, but it is now telling me that it isn't right. Here is my code.
def isItAStraight(aList):
count = 0
for i in set(aList):
count += 1
return aList.count(i) == 1
for some reason even if a number appears more than once it still gives true and I can't figure out why it won't give me false unless the first or last number are changed.
Each number has to occur only one time otherwise it is false.
So like take [1,2,3,4,5,6]
would be true.
But [1,2,2,3,4,5]
would be false.
Also, I can't import things like Counter or collections (though it would be so much easier to do it isn't apart of the assignment.)
The list is randomly generated from 1 to 6.
With a return inside the loop, you are only checking one value. You need to check each value. Also, instead of looping through the items of the list, you should loop through the items you're actually looking for. It would also help to make sure there are the correct number of items in the list.
def isItAStraight(aList):
if len(aList) != 6:
return False
for i in range(1, 7):
if aList.count(i) != 1:
return False
return True
But the easiest way to do this is to simply sort the list and check if it's what you're looking for:
def isItAStraight(aList):
return sorted(aList) == list(range(1, 7))
You need to be careful about what's inside the list. What you've written is a basically the same as the pseudo-code below:
let count = 0
for every unique element in aList:
Add 1 to count
if count is now 1, return true.
This will always return true if there is at least one element in aList, since you're adding 1 to count and then returning immediately.
A couple approaches to consider:
Create a 6 element list of all zeros called flags. Iterate over aList and set the corresponding element in flags to 1. If flags is all ones, then you return true.
Sort the list, then check if the first six numbers are 1, 2, 3, 4, 5, 6.
Given a list, I wanted to check if all the elements in that list are divisible by some given integer or not. Based on that, i have to return a boolean value.
l=[10,30,40,20]
For example - all the elements of this list are divisible by 5. Then, I would return True.
For 6, I would have returned False.
One approach I could think of is to generate an array consisting off boolean values and then AND them.
blist=[x%5==0 for x in l]
# [False, False, False, False]
# AND THE ELEMENTS
But this approach kind of feels bad. Can anyone suggest a more simple pythonic way out of this.
First of all, you want modulo division (%) as you want to see if it evenly divides by 5, so you are checking for a remainder, not the result of division.
You can use the all() builtin (which does what it says on the tin), but you don't need to generate a list, instead use a generator expression:
all(x%5 == 0 for x in l)
This has the advantage of being lazy, so as soon as a value isn't divisible it will return, saving computation
Using list comprehensions is pythonic. And you need to use mod not div.
Use all built in
res = all([x%5==0 for x in l])
You can do this more efficiently by
res = all(x%5 == 0 for x in l)
which uses a generator expression. In the first case python generates a list of all the mod values, in the second case the values are generated as they are needed by all and are hence only generated up to the first non-divisible value.
I started learning python today from the tutorial on the official site.
When reading about filter(function, sequence) i thought of making a function that returns if a number is prime to use it with the filter.
notDividedBy = [2,3,4,5,6,7,8,9]
def prime(num):
"""True if num is prime, false otherwise"""
copy = notDividedBy[:]
check = True
if num in copy:
copy.remove(num)
for x in copy:
if num % x == 0:
check = False
break
return check
The above code works in the shell.
My question is: Since i feel like although a solution, it is not the most elegant one, can anyone transform this code to something more python-like?(better structure? less lines?)
I believe it would help me for better understanding of the basics of the language.
The thing is, don't use any imports or anything, just simple staff.
Creating many many copies of lists is not a particularly efficient way of doing things. Instead use the xrange() (Python 2.x) or range() (Python 3) iterator. Here's one (naive) way you could implement a primality test:
from math import sqrt
def isPrime(n):
if n < 2: return False
if n == 2: return True
if not n % 2: return False #test if n is even
#we've already remove all the even numbers, no need to test for 2
#we only need to test up to sqrt(n), because any composite numbers can be
# factored into 2 values, at least one of which is < sqrt(n)
for i in xrange(3, int(sqrt(n)) + 1, 2):
if not n % i:
return False
return True
How about this one:
def is_prime(num):
return not any(num%i == 0 for i in xrange(2,num/2+1))
for i in xrange(10):
print i, is_prime(i)
Explanation
start with:
(num%i==0 for i in xrange(2,num/2+1))
This is a generator expression. I could have made it a list comprehension:
[num%i==0 for i in xrange(2,num/2+1)]
The list comprehension is equivalent to:
ll=[]
for i in xrange(2,num/2+1):
ll.append(num%i==0)
The difference between the generator and the list comprehension is that the generator only gives up it's elements as you iterate over it -- whereas the list comprehension calculates all the values up front. Anyway, from the above code, you can see that the expression generates a sequence of True's and False's. True if the number can be divided by i and False otherwise. If we generate a sequence of all False numbers, we know we have a prime.
The next trick is the any built in function. It basically searches through an iterable and checks if any of the values is True. As soon as it hits a True, it returns True. If it gets to the end of the iterable, it returns False. So, if the entire sequence is False (a prime number) then any will return False, otherwise it returns True. This would be perfect for a not_prime function, but our function is is_prime, so we just need to invert that result using the not operator.
The benefit of using the generator expression is that it is nice and concise, but also that it allows any to return before checking every value which means that as soon as it finds a number that divides num, it returns instead of generating all num/2 numbers.
Anyway, I hope this explanation is helpful. If not, feel free to leave a comment and I'll try to explain better.
One thing off the bat, if you are going to implement prime testing in this fashion, there's no reason to use an auxillary array
def prime(num):
"""True if num is prime, false otherwise"""
check = True
#if num in copy:
# copy.remove(num)
for x in range(2,x-1):
if num % x == 0:
check = False
break
return check
Here's a 2 liner using filter().
def prime(num):
"""True if num is prime, false otherwise"""
if num < 2:
return False
return len(filter(lambda x: num % x == 0, range(2, num))) == 0