Count negative values in a list of integers using Python? - python

I am having problems with this CodingBat question:
Given a list of integers, return the count of the negative values.
count_negative([-1, -2, -3]) → 3
count_negative([2, 2, 2, 2, 2]) → 0
count_negative([-5, -3, 4]) → 2
Why doesn't this code run correctly?
def count_negative(list):
for value in list:
total = 0
total += value
return total

You are setting total back to zero after every loop. Put it outside the loop:
Also, the function will break after the first loop, because after a function returns something it breaks. Also put return total outside of the loop:
total = 0
for value in list:
total += value
return total
I don't see how this will determine whether a number is a negative or not. You can use an if-statement inside of your loop.
if value < 0:
total += 1
Or you can just use a list comprehension:
sum(1 for i in lst if i < 0)
By the way, never name something list. It overrides the built-in. I'm rather surprised your question did it.

Turn it into a pd.DataFrame then use df[df>0].count()/len(df)

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.

in Python, I get a wrong total, i only get the total of the positive numbers that are located before the negative ones [duplicate]

This question already has answers here:
Sum list values within a given range using while loop
(2 answers)
Closed 2 years ago.
i wrote this code in python:
list=[3,5,7,6,-9,5,4]
i=0
total=0
while i<len(list) and list[i] > 0:
total+=list[i]
i+=1
print(total)
and instead of getting the total of all positive numbers i only get the total of numbers that are located before the negative one, i'm not sure what i'm doing wrong, this is just my fourth code in python i'd like some help^^
That is because you have the condition that the loop ends if you encounter a negative number. You can first remove that condition from the loop.
while i<len(list):
Next, you only want to add non-negative numbers so, use a conditional statement in the loop with the condition that you want.
if list[i] > 0:
Try to understand the working of while loop. It works as long as i < len(list and list[i] > 0. When it reaches the value -9, the while loop's second condition gets false and it terminates. Hence no sum is calculated after first negative integer is encountered.
To solve this, do
lis = [3, 5, 7, 6, -9, 5, 4]
sum = 0
for i in lis:
if i > 0:
sum += i
For your while loop code, use
lis = [3, 5, 7, 6, -9, 5, 4]
i = 0
sum = 0
while i < len(lis):
if lis[i] > 0:
sum += lis[i]
i = i + 1
Also, although you can use a variable name as list, it is advised not to do so in Python as list is also a keyword.
Do not use a while loop in this case. Iteration over items in a container is easier in Python with a for loop. Plus the logic is wrong and exits the while loop early when it fails the and list[i] > 0 condition.
lst = [3,5,7,6,-9,5,4]
total = 0
for item in lst:
if item > 0:
total += item
print(total)
Also, don't use list as a variable name. That replaces the built-in list type and is called "shadowing".
You can also use a list comprehension and simplify the code even more:
lst = [3,5,7,6,-9,5,4]
total = sum([item for item in lst if item > 0])
print(total)

How to find the product of the odd-indexed values in a list

I am able to solve this problem up the the 'even' part but I'm getting stuck in the odd part.
You will be given an array of n numbers. Your task is to first reverse the array (first number becomes last, 2nd number becomes 2nd from the last and so on) and then print the sum of the numbers at even indices and print the product of the numbers at odd indices.
Input
First line contains single integer N: number of elements
followed by N different integers separated by spaces
Output
Two space separated integers representing sum of the numbers at even places and the product of the numbers at odd places.
My code so far:
n = int(input())
arr = [int(x) for x in input().split()]
arr.reverse()
for ele in arr:
print(ele, end=" ")
print()
sum = 0
count = 1
while count <= n:
if count % 2 == 0:
sum += count
count += 1
print(sum)
There's a couple of issues in the code you've supplied which I'll address first:
Firstly, you need to be clear about what is meant by odd and even indices. In some languages (Matlab) for example, the first element of an array is index position 1. In Python and Java it's 0, so, whilst your example has assumed 1, it probably should be 0 unless otherwise specified.
Second, in your line sum+=count you're summing the index positions, not the index values, so that isn't what your question is asking for.
Last point on your code is that you've used sum as a variable name. Whilst that works, sum is also a Python keyword and you should avoid using them as variable names as if you later want to use the sum function, you will get the error TypeError: 'int' object is not callable because you've redefined the sum function to be an integer.
To the answer:
Considering the above, this provides the answer to part 1 by fixing your code:
total = 0
count = 0
while count < n:
if count % 2 == 0:
total += arr[count]
count += 1
print(total)
It's worth noting that as you're looking for even numbers, you could better write that as:
total = 0
count = 0
while count < n:
total += arr[count]
count += 2
print(total)
However, there are even easier ways to do this in much less code, and they involve list slicing. You can slice a list by specifying [start: end: step], so arr[::2] specifies a start of position 0 (the default), an end of the end of the list the default) and a step of 2. This means that if arr contains [1,2,3,4,5,6], then arr[::2] will be [1,3,5] (i.e. the values at all of the even indices) or if you specify a start position of 1 i.e. arr[1::2] you will get [2,4,6] (i.e. the values at all of the even indices).
So, rather using a while loop. You could use a for loop over just the even values:
total = 0
for even_val in arr[::2]:
total += even_val
print(total)
but for sum you can even more easily write is as a simple sum command on the list slice:
print(sum(arr[::2]))
Before Python 3.8, there was no simple equivalent of sum for product, so if you're using a lower version, you can either reuse the method above, allowing for the fact that you would need to prime the total with the first value, then multiply from the next one, i.e.:
total = arr[1]
count = 3
while count < n:
total *= arr[count]
count += 2
print(total)
or with a for loop:
total = arr[1]
for odd_val in arr[3::2]:
total *= odd_val
print(total)
But from Python 3.8 (documentation here) you can now import prod from the math library which will work in the same way as sum:
from math import prod
print(prod(arr[1::2]))
[Thanks #HeapOverflow for the nudge]
As this is for a problem set, it may not be an issue as all examples may have an array length N > 2, but the examples above do assume that there will be at least two entries in arr. If that's not the case, you should put in some validation before trying to access arr[1]
Here's a cute little recursive function to do that (assuming one-based indices):
# def prodSum(increment,multiplier=1,*rest): if zero based indices
def prodSum(multiplier,increment=0,*rest):
if not rest: return multiplier,increment
product,total = prodSum(*rest)
return (product * multiplier, total + increment)
x = [1,2,3,4,5]
print(prodSum(*reversed(x))) # 15,6

How to loop my definition? ~sum values untill limit is reached and loop again for the rest

I'm struggling with while looping.
I have a list with Widths (double or integer, doesn't matter - don't need precision).
Basically I need number of items that sum is lower than limit.
Now it finds only the first number.
I'm not able to adapt while loop, so it would start calculation over again with the rest of items.
This code give 6 as output, cause sum(100,300,30,100,50,80) < limit = 850.
The desired loop would do this:
1st iteration: start from 0 until sum meet limit: [100,300,30,100,50,80,400,120,500,75,180] -> give 6
2nd iteration: start from the next(last index from 1st run +1) item and iterate over the rest: 400,120,500,75,180 -> give 2
3rd: iterate over 500,75,180 -> give 3
Number of widths = unknown
if width > limit -> break the code
Widths = [100,300,30,100,50,80,400,120,500,75,180]
def items(nums,limit):
sum=0
for i in range(0,len(nums)):
sum += nums[i]
if sum>limit-1:
return i
print (items(Widths,850))
I'd like to have output like this:
[6,2,3]
a return immediately exits out of the function. You need to store instead of returning, and go from there.
I have also pointed out some comments in code as well that should help.
Widths = [100,300,30,100,50,80,400,120,500,75,180]
def items(nums,limit):
acc = 0 #do not use sum as a variable name. it "shadows" or hides the builtin function with same name
length = 0
result = []
for num in nums: #You do not really need indexes here, so you can directly iterate on items in nums list.
acc += num
if acc >= limit: #greater than or equal to.
result.append(length)
acc = num
length = 1
else:
length += 1
result.append(length) #if you need the last length even if it does not add up.
return result
print (items(Widths,850))
#Output:
[6, 2, 3]

Why is variable behaving differently outside loop?

if i run this code:
def numbers_in_lists(string):
next_number = 0
count = 0
final_list = []
while count < len(string):
number = int(string[count])
if number > next_number:
final_list.append(number)
new = []
next_number = number
else:
new.append(number)
if new not in final_list:
final_list.append(new)
count += 1
print final_list
#testcases
string = '543987'
result = [5,[4,3],9,[8,7]]
print repr(string), numbers_in_lists(string) == result
i get this answer:
'543987' [5, [4, 3], 9, [8, 7]]
False
but if i put the number variable outside of the while loop like this:
def numbers_in_lists(string):
next_number = 0
count = 0
final_list = []
number = int(string[count])
while count < len(string):
if number > next_number:
final_list.append(number)
new = []
next_number = number
else:
new.append(number)
if new not in final_list:
final_list.append(new)
count += 1
print final_list
i get this answer:
'543987' [5, [5, 5, 5, 5, 5]]
False
I am a beginner and i have looked everywhere for the explanation as to why the number variable behaves differently outside of the loop? Also, why are the other variables ok outside of the loop but not number variable?
Any help would be much appreciated. Thankyou. :)
You declare number as
number = int(string[count])
So when
count = 0
This means that number will be the first character of your string (position [0]) converted to int. If you do not update number within your loop, it will never change. In your first version of the code, number is in your while loop.
while count < len(string):
number = int(string[count])
# more code
count += 1
Note at the end of the loop, you increment count. This means at the beginning of the next iteration, count now is incremented, so number will take on the value of the next character in your string.
A common misconception for beginners is that a variable is somehow "bound" to another variable. For example:
>>> a = 5
>>> b = a
>>> b
5
>>> a = 7
>>> b
5
See, even though a changed values from 5 to 7, b doesn't change because it is not "bound" to that variable in any way. The line b = a means "take the value from a and assign it to b" after that, b doesn't care what happens to a.
The number = int(string[count]) uses the value of count assigned outside the loop which is the first character index 0, it will never change outside the loop, so you will always get the original value appended which is the first character.
Using number = int(string[count]) inside the loop you are reassigning number to the value of the element at index count each time so you get a different part of the input string appended each time.
Once you enter the while loop any values you change that were defined outside of the loop will not change outside that loop, you must reassign the value inside the loop.
I get that you are a beginner. Here is a rewrite that should help you with some useful python idioms and constructs:
def numbers_in_lists(string):
numbers = [int(c) for c in string]
next_number = -1
final_list = []
for number in numbers:
if number > next_number:
final_list.append(number)
final_list.append([])
next_number = number
else:
final_list[-1].append(number)
final_list = [x for x in final_list if x != []]
print final_list
First, be suspicious when you have a while-loop and a counter. You can replace it with a for-loop that iterates over all the items.
Since this code operates on integers, not characters in a string, let's translate them all at once using a list comprehension:
numbers = [int(c) for c in string]
This creates a list that has all the characters translated to integers.
By setting next_number = -1, we ensure that all numbers in numbers will be greater. In particular, the first element will be greater.
When we find a number that exceeds our last maximum, next_number, we add number and a bucket to put succeeding numbers less than number into:
if number > next_number:
final_list.append(number)
final_list.append([])
next_number = number
That means when we add 5, final_list looks like this:
[5, []]
And when number is 4 and 3, they get added properly:
[5, [4]]
[5, [4, 3]]
How does that happen? This code does it:
else:
final_list[-1].append(number)
Here we do not append to final_list; we append to the last list in final_list, final_list[-1].
But what if our sequence was just 5? Then at the end of the loop, final_list would look like this:
[5, []]
In that case, we want to trim out all empty lists, so we do it like this:
final_list = [x for x in final_list if x != []]
This says, "make final_list into a list that has all elements of final_list except those that are empty lists."
Good luck with learning python. I hope you find it rewarding.

Categories