Negative number finder in index and occuring - python

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.

Related

Function that returns the length of the longest run of repetition in a given list

I'm trying to write a function that returns the length of the longest run of repetition in a given list
Here is my code:
def longest_repetition(a):
longest = 0
j = 0
run2 = 0
while j <= len(a)-1:
for i in a:
run = a.count(a[j] == i)
if run == 1:
run2 += 1
if run2 > longest:
longest = run2
j += 1
run2 = 0
return longest
print(longest_repetition([4,1,2,4,7,9,4]))
print(longest_repetition([5,3,5,6,9,4,4,4,4]))
3
0
The first test function works fine, but the second test function is not counting at all and I'm not sure why. Any insight is much appreciated
Just noticed that the question I was given and the expected results are not consistent. So what I'm basically trying to do is find the most repeated element in a list and the output would be the number of times it is repeated. That said, the output for the second test function should be 4 because the element '4' is repeated four times (elements are not required to be in one run as implied in my original question)
First of all, let's check if you were consistent with your question (function that returns the length of the longest run of repetition):
e.g.:
a = [4,1,2,4,7,9,4]
b = [5,3,5,6,9,4,4,4,4]
(assuming, you are only checking single position, e.g. c = [1,2,3,1,2,3] could have one repetition of sequence 1,2,3 - i am assuming that is not your goal)
So:
for a, there is no repetitions of same value, therefore length equals 0
for b, you have one, quadruple repetition of 4, therefore length equals 4
First, your max_amount_of_repetitions=0 and current_repetitions_run=0' So, what you need to do to detect repetition is simply check if value of n-1'th and n'th element is same. If so, you increment current_repetitions_run', else, you reset current_repetitions_run=0.
Last step is check if your current run is longest of all:
max_amount_of_repetitions= max(max_amount_of_repetitions, current_repetitions_run)
to surely get both n-1 and n within your list range, I'd simply start iteration from second element. That way, n-1 is first element.
for n in range(1,len(a)):
if a[n-1] == a[n]:
print("I am sure, you can figure out the rest")
you can use hash to calculate the frequency of the element and then get the max of frequencies.
using functional approach
from collections import Counter
def longest_repitition(array):
return max(Counter(array).values())
other way, without using Counter
def longest_repitition(array):
freq = {}
for val in array:
if val not in freq:
freq[val] = 0
freq[val] += 1
values = freq.values()
return max(values)

PYTHON: Find index of the largest number in a list without built-in functions and list modules

Write a function, max index, that takes a list as a parameter and returns the index of the largest number in the list.
When writing the function, you are given the following rules:
You are not allowed to use the max function
You are not allowed to use any list methods
You must use a Pythonic FOR loop. This means you CANNOT use the range function or enumerate function in your loop
If the largest number appears more than once, you should return the smallest index
This is so wrong because it fails to loop through the list and I also don't know how to compare the two indexes in case the largest value appears more than once in the list.
def max_index(lon):
"""
input is a list of numbers.
returns the index of the largest number in the list
"""
max = lon[0]
index = 0
for n in lon:
if n>max:
max = n
index+=1
return index
This might not be the most effecient approach, but I'm pretty sure this would work:
def max_index(lon):
current_index = 0
largest_index = 0
max = 0
for item in lon:
if item > max:
max = item
largest_index = current_index
current_index += 1
return largest_index
Here is one solution. If this is a homework question, you wont learn without trying, so try out different solutions starting with the for loop. Good luck!
def max_index(lon):
max_val=0
counter=0
max_index=0
for num in lon:
if num > max_val:
max_val = num
max_index = counter
counter = counter + 1
return max_index

In a function ,How can I assign the value to a set?

I'm trying to make a program that finds the perfect number.(Perfect number=The sum of its divisors except itself is a number equal to itself.)And I want to add one more thing. Firstly I want to define an empty list and put the perfect numbers in it.But When I run the programm I didn't take the right throughput.How can I solve this problem.
My cods
def perfect(number):
total = 0
for i in range(1,number):
if number % i == 0:
total += i
return total
perfect_number_set = []
for i in range(1,1001)
if perfect(i):
perfect_number_set += [perfect(i)]
print(perfect_number_set)
print(i)
The output of the codes I wrote
[True]
6
[True,True]
28
[True,True,True]
You have following issues in your code:
Your implementation of perfect method is incorrect. You need to return True/False if a number is perfect. You are returning the total which is not correct.
Missing colon : in the for loop
def perfect(number):
total = 0
for i in range(1,number):
if number % i == 0:
total += i
return total == number
perfect_number_list = []
for i in range(1,1001):
if perfect(i):
print(i)
perfect_number_list.append(i)
print(perfect_number_list)
There is a difference between set and a list in python. You have used a list.
Set contains only unique entries.
Best practice tip:
defining a list use :
list_name = list()
Better way of adding items to as list by using it's method
list_name.append(list_item_to_add)
Another thing is that returning a number and checking it in if without any condition is not readable. Change it to:
if perfect(i) != 0:
(Altho Yours implementation work, because python if treats 0 like False and any other value as True)

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]

returning indices using a while loop

I'm trying to take an input of a list of numbers and return the list of indices in the original list that contain negative values. I also want to use a while loop. Here is my code so far.
def scrollList2(myList):
negativeIndices = []
i = 0
while i < len(myList):
if myList[i] < 0:
i = i + 1
negativeIndices.append(i)
return negativeIndices
How to I stop the loop and how do i get the indices to return? Right now when I run it, it runs forever (infinite loop) how do I tell it to stop once it hits the last indices of myList?
When you hit your first non-negative number, the if is never entered again and i never gets incremented again. Put the part where you increment i outside the if block.
while i < len(myList):
if myList[i] < 0:
i = i + 1
negativeIndices.append(i)
Assume, the conditional myList[i] < 0 is not true. In that case, i won’t be incremented and nothing else happens either. So you will end up in the next iteration, with the same value of i and the same conditional. Forever, in an endless loop.
You will want to increment i regardless of whether you matched something or not. So you will have to put the increment outside of the if conditional. Furthermore, you want to increment i after appending the index to the list, so you actually append the index you tested, and not the one afterwards:
while i < len(myList):
if myList[i] < 0:
negativeIndices.append(i)
i = i + 1
Also, you would usually use a for loop here. It will automatically take care of giving you all the values of i which you need to index every element in myList. It works like this:
negativeIndices = []
for i in range(len(myList)):
if myList[i] < 0:
negativeIndices.append(i)
range(len(myList)) will give you a sequence of values for every number from zero to the length of the list (not including the length itself). So if your list holds 4 values, you will get the values 0, 1, 2 and 3 for i. So you won’t need to take care of incrementing it on your own.
Another possibility would be enumerate as Foo Bar User mentioned. That function will take a sequence, or list in your case, and will give you both an index and the value at the same time:
negativeIndices = []
for i, value in enumerate(myList):
if value < 0:
negativeIndices.append(i)
As you can see, this completely removes the need to even access the list by its index.
OP wants to use a while loop, so this answer is not exactly on point - but I feel I should point out that many pythonistas will expect something like:
neg_indices = [k for k,v in enumerate(myList) if v < 0]
This is implicit in the other answers, however it might be useful for lurkers and for OP to consider down the road... While certainly does the job as the other answers show, but its 'free' in a list comprehension; plus, there's no chance of an infinite loop here....

Categories