Given an array of ints, return True if .. 1, 2, 3, .. appears in the array somewhere.
def array123(nums):
for i in nums:
if nums[i:i+3] == [1,2,3]:
return True
return False
Coding bat problem
my code is satisfying all the test cases except for nums=[1,2,3]
can someone tell me whats wrong with my code
It should be like this.
def array123(nums):
for i in range(len(nums)):
if nums[i:i+3] == [1,2,3]:
return True
return False
Try this. Hope this helps. :)
Your code is not completely right. You're slicing the list with the items in the list, not with indices. Luckily, this did not throw any error because the items in the list are within the bounds of the list's indices or rather slicing does not raise errors, when done correclty, irrespective of start and/or stop indices.
You can use range(len(...)) to generate the indices, and you may stop the search at len(nums) - len(sublist), so you don't check for slices less than the length of the sublist. This comes more handy as the length of the sublist gets larger.
def array123(nums, sublist):
j = len(sublist)
for i in range(len(nums)-j):
if nums[i:i+j] == sublist:
return True
return False
# Call function
array123(nums, [1,2,3])
Useful reference:
Explain Python's slice notation
You're getting wrong result because you're iterating on the value of elements not on the index of elements of elements. Try following code
def array123(nums):
for i in range(len(nums)-2):
if nums[i:i+3] == [1,2,3]:
return True
return False
And remember to give the end index of list (range(len(nums)-2)) because suppose if length of your array is 4 then (range(len(nums)-2)) will be
(range(2)) = [0,1]
So the loop will iterate for 0,1 as starting index
Related
Sorry for noob question. Just started learning coding with Python - beginners level.
Wasn't able to find in the net what I require.
Creating function to loop through the entire line, in order to find right combination - 7,8,9 - regardless of input length and of target position, and return 'true' if found. Wasn't able to devise the function correctly. Not sure how to devise function clearly and at all this far.
Your help is much appreciated.
This is what I came up with so far (not working of course):
def _11(n):
for loop in range(len(n)):
if n[loop]==[7,8,9]:
return True
else:
return False
print(_11([1000,10,11,34,67,89,334,5567,6534,765,2,3,5,6,112,7,8,9,11111]))
It always returns False. Tried with (*n) to no avail.
The answer offered by #Carson is entirely correct.
I offer this not really as an answer to the question but as an alternative and more efficient approach.
In OP's question he is looking for an occurrence of 3 consecutive values described by way of a list. Let's call that a triplet.
If we iterate over the input list one element at a time we create lots of triplets before comparing them.
However, we can make this more efficient by searching the input list for any occurrence of the first item in the target triplet. In that way we are likely to slice the input list far less often.
Here are two implementations with timings...
from timeit import timeit
def _11(n, t):
offset = 0
lt = len(t)
m = len(n) - lt
while offset < m:
try:
offset += n[offset:].index(t[0])
if n[offset:offset+lt] == t:
return True
offset += 1
except ValueError:
break
return False
def _11a(n, t):
for index in range(len(n) - len(t)):
if n[index:index + len(t)] == t:
return True
return False
n = [1000,10,11,34,67,89,334,5567,6534,765,2,3,5,6,112,7,8,9,11111]
t = [7, 8, 9]
for func in _11, _11a:
print(func.__name__, timeit(lambda: func(n, t)))
Output:
_11 0.43439731000012216
_11a 1.8685798310000337
There are two mistakes with your code.
Indexing into a loop returns 1 element, not multiple. When you write n[loop], you're getting 1 value, not a list.
You shouldn't return false that early. Your code exits after the first step in the loop, but it should go through the entire loop before returning false.
Consider the following snippet:
def has_subarr(arr, subarr):
"""Tests if `subarr` exists in arr"""
for i in range(len(arr)):
if arr[i:i+len(subarr)] == subarr:
return True
return False
This code is more general than your example, it accepts the value to check for as another argument. Notice the use of : in the array access. This allows you to return multiple elements in an array. Also notice how the return False is only reached once the entire loop has completed.
First, n[loop] return a single element, not a sublist. You should use n[loop+3]. But this will introduce a problem where loop+3 exceeds the length of the list. So the solution may be:
def _11(n):
for loop in range(len(n)-3):
if n[loop:loop+3]==[7,8,9]:
return True
else:
return False
print(_11([1000,10,11,34,67,89,334,5567,6534,765,2,3,5,6,112,7,8,9,11111]))
Your actual code return during the first iteration. You only test once. You must modify the indentation as in:
def _11(n):
target = [7,8,9]
for index in range( len(n) - len(target)):
if n[index:index + len(target)] == [7,8,9]:
return True
return False
print(_11([1000,10,11,34,67,89,334,5567,6534,765,2,3,5,6,112,7,8,9,11111]))
You can try checking the str representation of the 2 lists:
import re
def _11(n):
if re.search("(?<![0-9-.'])7, 8, 9(?![0-9.])",str(n)):
return True
return False
print(_11([27,8,9]))
The Output:
False
Here is my code:
def isSorted(arr):
n = len(arr)
if n == 0 or n == 1:
return True
elif arr[n-2] > arr[n-1]:
return False
return isSorted(arr[0:n-1])
arr = [1,9,9,4,5]
isSorted(arr)
if isSorted:
print("yes")
else:
print("no")
Answer is always yes, even if the array is unsorted. Can anybody please explain what mistake am I making?
Your code was fine with the exception of the error noted in the comments: you were ignoring the return value of isSorted(arr) by just checking if isSorted:. isSorted is a callable (and not None or zero or an empty string, etc.) and thus evaluates to True.
Here's a slight modification to your code, using negative indices to count back from the end of the array. For example, -2 is the same as n-2 when n is the length of the array.
I've also thrown in a little syntactic sugar at the end, using python's ternary operator.
def isSorted(arr):
if len(arr) < 2:
return True
elif arr[-2] > arr[-1]:
return False
return isSorted(arr[:-1])
arr = [1,9,9,4,5]
print("yes" if isSorted(arr) else "no")
A recursive approach can be implemented like this:
def isSorted(lst):
if len(lst) < 2:
return True
return False if lst[1] < lst[0] else isSorted(lst[1:])
However, it's going to be slow compared with:
lst == sorted(lst)
...due to the efficient implementation of the sort() function
As others have pointed out, there are non-recursive solutions which will outperform recursive implementations.
Having said that, if you insist on using recursion you should seek approaches that will not give you a stack overflow with larger arrays. Solutions which whittle the size of the problem down one element at a time will cause stack overflow on arrays that are larger than ~1000 elements. To avoid this, use an approach which cuts the problem size in half at each level of the recursion. The following algorithm does this:
def isSorted(ary):
if len(ary) < 2:
return True
mid = len(ary) // 2
return (ary[mid-1] <= ary[mid]) and isSorted(ary[:mid]) and isSorted(ary[mid:])
The logic is:
Arrays of length less than 2 are trivially considered sorted, so return True if this is the case;
Otherwise, find the mid-range value which will split the array into two sub-arrays which differ in length by no more than one;
The array is sorted if and only if the last element of the first sub-array is ≤ the first element of the second subarray, and both sub-arrays are sorted.
Since and is used, short-circuiting can occur. The recursive stack size is O(log(len(ary)).
As Mark pointed out, the reason you always get "yes" is because isSorted, without an argument, is a reference to the function and is considered "truthy" in python.
def isSorted(arr):
n = len(arr)
if n == 0 or n == 1:
return True
elif arr[n-2] > arr[n-1]:
return False
return isSorted(arr[0:n-1])
arr = [1,9,9,4,5]
#isSorted(arr)
#You should use "if isSorted(arr):" instead of "isSorted(arr)".
if isSorted(arr):
print("yes")
else:
print("no")
Simply add the parameters to the function in the if statement:
if isSorted(arr):
print("yes")
else
print("no")
#here is the code
def has_33(nums):
for i in range(0,len(nums)-1):
if nums[i:i+2]==[3,3]:
return True
return False
nums = [1,2,3,3]
print(has_33(nums))
questions:
why the code used len(nums)-1 in second line?(why used -1 ?)
in the 3rd line why do they used [i:i+2]==[3,3] and how does this code perform ?
please let me know ,
i am basically a noob in coding right now please help me to under stand how this code works
If you're looking for two elements in a row, there's no point in checking the last element of the list, since there's nothing after it. So the loop stops at the 2nd-to-last index.
nums[i:i+2] returns a slice of the list from element i to element i+1. Those are 2 consecutive elements. Then it compares this to [3, 3] to see if that pair of elements are two 3's next to each other.
Because a list of the length n has only n-1 pairs (for example, [1,2,3,4] has [1,2], [2,3] and [3,4])
Beacuse list[x:y] does not return element y of the list.
The following code is simple and should work for what you want to do.
a=[0, 1, 2, 0, 3]
def has_33():
last_i = 0
for i in a:
if last_i==3 and i==3:
return True
if i==3:
last_i = 3
return False
print(has_33())
Also works in different combinations of ...3,3...
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 tried solving the question below on codingbat:
"Given an array of integers, return True if the sequence of numbers 1, 2, 3 appears in the array somewhere".
This was my solution which returned with the error "index out of range":
def array123(nums):
for i in range(len(nums)):
if nums[i]==1 and nums[i+1]==2 and nums[i+2]==3:
return True
return False
This was Codingbat's solution:
def array123(nums):
for i in range(len(nums)-2):
if nums[i]==1 and nums[i+1]==2 and nums[i+2]==3:
return True
return False
I know I'm missing a trick here. Please could someone explain why I have to iterate over range(len(nums)-2)??
Thank you.
thats not exactly an amazing solution either, this would be proper:
def array123(nums):
for i in range(len(nums)-2):
if nums[i:i+3] == [1,2,3]:
return True
return False
print(array123([1,2,3]))
True
the main differences between your code and codingbat's is how the range is used
your range is the length of the list right? so since you are adding to the index by 2 at the highest case, we only should iterate until the length - 2, because anything over reaches past the highest index
They have used len(num) -2 , so that the num [i+2] points to the last element and not a index outside of the num
Thats because you are checking i th , i+1 th and i+2 th elements in the loop.
The requirement is to check 1,2,3 in the array anywhere.
and in python indices starting at zero, so range(len(num)-2) makes it to iterate over 0 to 7, if it is 10 elements array.