Looping through indices in array by 3s - python

I am attempting to create a function that check to see if the sum of three consecutive numbers in an array are equal to 7.
The first three indices in the list seem to work. However, my for loop does not continue throughout the entirety of the list. How do I resolve this?
def seven(array):
three = []
count = 0
for num in array[count::count+3]:
three.append(num)
if sum(three) == 7:
return True
break
else:
count += 1
continue
print(seven([1,1,5,0,6,1]))

The problem is that the array you are iterating over is created just once - on the beginning of iteration.
def seven(array):
for i in range(len(array)-2):
three = array[i:i+3]
if sum(three) == 7:
return True
return False

You can iterate through your array by steps of 3 using python's range method. range(0,len(array)-2,3) will go from 0 to 3 less than the total length of the array, adding three after each pass
Then, in your call to sum(), you can use array splitting to get the sum of the next 3 objects
def seven(array):
three = []
count = 0
for num in range(0,len(array)-2,3):
three.append(num)
if sum(array[num:num+3]) == 7:
return True
return False
print(seven([1,1,5,0,6,1]))

Related

checking duplicates in list using while loop

I'm trying to check for duplicate numbers within a list using only while loops and if statements. For some reason it is returning True for the list [1, 2, 3, 4, 5, 6] and I can't figure out why.
def has_duplicates(xs):
count = 0
while count < len(xs) and len(xs) > 1:
check = 1
while check < len(xs):
if xs[check] == xs[count]:
return True
else:
check += 1
count += 1
return False
I get the correct output using your function. However, there are certainly easier ways to get the same result, as:
def has_duplic2(xs):
return len(set(xs)) != len(xs)
In your first algorithm you shouldn't assing to the check variable the value of 1.
Otherwise on the second cycle of the loop both count and check will be 1 and you'll be comparing the element [1] of your list with itself, which will always return true.
Instead you should set the check variable to check = count + 1. So that you never compare a value with itself.

Find The Parity Outlier using dictionary {Python}

during the Kata on Codewars called 'Find The Parity Outlier' I faced a problem, and have been trying to solve it using dictionary. I pass almost all tests except 4.
Instruction for the Kata is:
You are given an array (which will have a length of at least 3, but could be very large) containing integers. The array is either entirely comprised of odd integers or entirely comprised of even integers except for a single integer N. Write a method that takes the array as an argument and returns this "outlier" N.
The function is:
def find_outlier(integers):
d = dict()
count = 0
count1 = 0
for i in range(len(integers)):
if integers[i] % 2 != 0 :
d['odd'] = integers[i]
else:
d['even'] = integers[i]
for j in range(len(integers)):
if integers[j] % 2 == 0:
count += 1
else:
count1 += 1
if count > count1:
return d['odd']
return d['even']
Test Results:
2 should equal 1
36 should equal 17
36 should equal -123456789
0 should equal 1
So the question is? Why is it so? Can you help me to sort the problem out? Thanks a lot!
I'm not sure what exactly you're referring to with that list of test results. In general though, your method with the dictionary seems like it might be overcomplicating things a bit as well. You shouldn't need to use a dict, and you shouldn't need two for loops either. Here's an alternative solution to this problem using only list comprehension.
def find_outlier(arr):
# input should be an array-like of integers (and length >= 3) with either only one odd element OR only one even element
odd_mask = [n%2 != 0 for n in arr] # boolean array with True in the location(s) where the elements are odd
even_mask = [n%2 == 0 for n in arr] # boolean array with True in the location(s) where the elements are even
N_odd = sum(odd_mask) # number of odd elements in the input
N_even = sum(even_mask) # number of even elements in the input
if N_even == 1: # if even is the 'outlier'...
return arr[even_mask.index(True)] # return the element of the input array at the index we determined we had an even
elif N_odd == 1: # if odd is the 'outlier'...
return arr[odd_mask.index(True)] # return the element of the input array at the index we determined we had an odd
else: # something has gone wrong or the input did not adhere to the standards set by the problem
return None
And even this is technically not as efficient as it could be. Let me know if you try this and whether it solves whatever issue you were experiencing with expected results.
In your code the final part should not be in the else block, nor even in the for loop:
if count > count1:
return d['odd']
return d['even']
Like this is may give a wrong result. For instance, if the first number in the input is odd, and is the only odd one, then this code will return d['even'] which is obviously wrong.
Place these lines after the loop (with correct indentation) and it should work.
However, this problem can be solved without dictionary or extra lists. Have a go at it.
def find_outlier(integers):
parity = integers[-2] % 2
if integers[-1] % 2 != parity:
if integers[0] % 2 != parity:
return integers[-2]
else:
return integers[-1]
for i in integers:
if i % 2 != parity:
return i

How to find duplicate values from a new array in Python?

I'm still extremely new to python, and currently stuck on this problem. Basically, I take a list of numbers and add them to each other, starting at zero. The code writes out each line into a new array. If in this new array I find two of the same numbers, it stops and returns that number. The original list of values repeats itself if no duplicate is found.
Here's what I have so far:
file = open("list.txt", "r")
array1 = file.readlines()
total = 0
finalValue = 0
for i in range(0,len(array1)):
array1[i] = int(array1[i])
array2 = []
i = 0
counter = 0
while finalValue == 0:
total += array1[i]
array2.append(total)
print(array2)
for c in range(0,len(array2)):
if (total == array2[c]):
counter += 1
if counter == 2:
finalValue = total
break
if (i == len(array1)-1):
i = 0
else:
i += 1
counter = 0
print(finalValue)
I think the counter is working, but it never finds a duplicate, i.e. it never hits the second counter.
There are plenty of ways to make your code simpler in Python, but first of all, your problem is that the condition total == array2[c] compares elements of the array with your total, not with each other. For example, if your array is [1,3,3], the second 3 would be compared to 4, not to 3.
If I understand your code, I think you want to change total == array2[c] to array1[i] == array2[c] - but that's just an immediate fix, you can use python's list techniques to make this code much simpler.

Negative number finder in index and occuring

Write a func/on first_neg that takes a (possibly empty) list of
numbers as input parameter, finds the first occurrence of a
nega/ve number, and returns the index (i.e. the posi/on in the
list) of that number. If the list contains no nega/ve numbers or it
is empty, the program should return None. Use while loop (and
not for loop) and your while loop should stop looping once the
first nega/ve number is found.
This is the question my teacher asked me any ideas this what i did:
def first_neg(list):
count = 0
for number in list:
if number < 0:
count += 1
return count
Dosent seem to work properly i just joined 1st post hope can get some help
x = [1,2,3,-5]
def first_neg(list):
count = 0
for number in list:
count += 1 #moved it outside of the if
if number < 0:
return count
print(first_neg(x)) #prints 4
You want to increment count not when you've found the answer but everytime the forloops loops. Note that this method returns 4 which is the fourth item in the list, not the index, Index of the list starts from 0 so to access it would be 3. Take our list x = [1,2,3,-5], -5 is in the fourth slot of the list, but to access it we have to call x[3] since lists starts at 0 indexing.
If you want to return the index of the list where the first negative number is found try this:
x = [1,2,3,-5]
def first_neg(list):
for count, number in enumerate(list):
if number < 0:
return count
print(first_neg(x)) # prints 3
This is because enumerate creates a "pairing" of the item in the list and it's the current count. Enumerate just counts from 0 everytime it gets an item out of the list.
Also as a side note ( I didn't change it in my answer since I wanted you to understand what's going on ). Don't name your variables keywords like list, tuple, int, str... Just a bad idea and habit, it works as you can see but it can cause issues.
Return the index immediately once you encounter the negative element. Increment the index otherwise:
def first_neg(lst):
count = 0
while count < len(lst):
if lst[count] < 0:
return count
count = count + 1
return None
Note : Better if you use enumerate() rather than using extra count variable. The code you mentioned is not written in pythonic way.
You may try this as well:
def first_neg(lst):
res = [i for i,x in enumerate(lst) if x<0]
return None if res == [] else res[0]
The code above can be improved using generators as suggested by #Chris_Rands.

Python: Does list contain 3 consecutive integers that sum to 7?

I am working through the prep materials for my application to a coding bootcamp. This is a practice problem I am struggling with (using Python):
"Write a function 'lucky_sevens(numbers)', which takes in a list of integers and print True if any three consecutive elements sum to 7.
Make sure your code correctly checks for the first and last elements of the array."
I know how to loop through an array one element at a time, but don't know how to "hold" one element while also assessing the second and third elements in relation to the first, as this prompt requires. As you can see from my attempt below, I'm not sure when/where/how to increment the index values to search the whole list.
def lucky_sevens(numbers):
index1 = 0 # For assessing 1st of 3 numbers
index2 = index1 + 1 # For assessing 2nd of 3 numbers
index3 = index2 + 1 # For assessing 3rd of 3 numbers
# If all index values are within the list...
if index1 <= (len(numbers) - 2) and index2 <= (len(numbers) - 1) and index3 <= len(numbers):
# If the values at those indices sum to 7...
if numbers[index1] + numbers[index2] + numbers[index3] == 7:
print True
else:
print False
# I think the increments below may be one of the places I am incorrect
index1 += 1
index2 += 1
index3 += 1
When I run
lucky_sevens([2, 1, 5, 1, 0])
It is printing False, I think because it is only considering elements in the 0th, 1st and 2nd positions (sums to 8, not 7, as required).
It should print True, because elements in the 1st, 2nd and 3rd positions sum to 7. (1 + 5 + 1 = 7).
Can anyone please provide a suggestion? I would be most appreciative.
Yes, for your case its only considering the first, second and third elements. This is because you do not have any loops in your function.
In Python loop constructs are for and while . So you would need to use either one.
I can give you some hints to the problem , not going to provide you the complete code (since otherwise how would you learn?) -
You need to loop through the indexes from first index (0) to the len(numbers) -2 . An easy function that can help you do this would be enumerate() , it spits out the index as well as actual element when iterating over it using for loop (If you are using enumerate , you would need to put a condition to check that index should be less than len(numbers) - 2).
You should then get the elements from index+1 pos and index+2 position as well, and sum them and check if thats equal to 7 , if so you should return True.
A common mistake many make is to return False if the above (2) condition is not met, but actually what you need to do is to return it only when there are no matches at all (at the end of the function) .
You need a loop through the list to evaluate all elements. In your code, you only evaluate the first 3 elements.
Try this:
def lucky_sevens(numbers):
for i in range(0, len(numbers)):
if sum(numbers[i:i + 3]) == 7:
print True
return
print False
The reason yours doesn't work is because you're not looping it, you only check the first 3 elements in the list.
What about using recursion?
def lucky_sevens(numbers, index=0):
if index <= len(numbers):
if sum(numbers[index:index + 4]) == 7:
return True
else:
index += 1
return lucky_sevens(numbers[1:], index)
return False

Categories