Terminal returns nothing - python

this is the challenge :
This next function will give us the values from a list at every odd index. We will need to accept a list of numbers as an input parameter and loop through the odd indices instead of the elements. Here are the steps needed:
Define the function header to accept one input which will be our list of numbers
Create a new list which will hold our values to return
Iterate through every odd index until the end of the list
Within the loop, get the element at the current odd index and append it to our new list
Return the list of elements which we got from the odd indices.
and This is my solution :
def odd_indices(lst):
odd_list = []
index = 1
while index % 2 != 0 and index < len(lst):
odd_list.append(lst[index])
index +=1
return odd_list
print(odd_indices([4, 3, 7, 10, 11, -2]))
This doesnt return [3] only . can you help me figure out why ?

You check the parity in the loop control, instead of inside the loop.

Related

Unexpected error: "IndexError: list index out of range" when trying to access a list within a function

def myMax(L):
print(L)
f=len(L)
ind=0
maxx=L[0]
for i in range(len(L)):
if L[i]>maxx:
maxx=L[i]
ind=i
return (ind,maxx)
print(myMax([1, 2, -9, 10]))
print(myMax([]))
I am quite new to python. Above is code that I have written which takes a list as input and returns a tuple with the index of the highest number and the highest number itself.
For some reason I am getting an "IndexError:list index out of range" on line 5, where "maxx=L[0]"
Any help would be appreciated
You pass empty list : myMax([]) to the function and you point to the first element of this empty list L[0]. You need to check if the list L is not empty.
Adding the below as the first lines of the function will help you to protect against None or empty list
if L is None or len(L) == 0:
raise ValueError('Input list can not be None or empty')
Because you are calling the function on an empty list on the last line of your code.
print(myMax([]))
The argument you are passing to myMax function is [] that have length of zero.
When you call the fifth line your are actually trying to access the first element of the list, that does exist. In fact list in Python are indexed from 0 to n - 1 where n is the size of the list.
By default when you try to access an array on an index that it does not contain, the interpreter raise the exception IndexError: list index out of range. There are several ways to handle this cases for example the try except control, but in your case since the function in returning an integer I suggest you to append a control at the very end in order to return -1 in such cases.
def myMax(L):
if len(L) == 0:
return -1
# your code here
In this way you will not try an out of bound access and you have a return code representing the error occurred.

Not able to understand Python3 enumerate()

Question: Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
class Solution:
def twoSum(self, nums, target):
lookup={}
for cnt, num in enumerate (nums):
if target-num in lookup:
return lookup[target-num], cnt
lookup[num]=cnt
I am not able to understand the steps after for loop is used.I am new on Python, someone please help me.
Let me help you understand by explaining what the code does and how it solves the problem.
We need to find two numbers that sum to 9, to achieve this, we can iterate over every number in the array and then look if we already encountered a number that equals the target number minus the number we are currently on. If we haven't encountered such a number yet, we store the current number and its corresponding index.
Because we need to return the indices, we want to be able to look for the number-target pairs and immediately get the index. The solution uses a dictionary to store a number (key) and return an index as (value).
We iterate over every number, if we already encountered target-number before, we can return the current index and the index of the target-number, if we haven't encountered that number, we simply store the current number and its index.
The enumerate part, simply provides an index along with the value of the array that is being iterated, in the form of (id, item).
class Solution:
def twoSum(self, nums, target):
# Here a dictionary is created, which will store value, index as key, value pairs.
lookup={}
# For every number in the array, get the index (cnt) and number (num)
for cnt, num in enumerate (nums):
# If we find target-num, we know that num + target-num = target
if target-num in lookup:
# Hence we return the index of the target-num we stored in the dict, and the index of the current value (cnt)
return lookup[target-num], cnt
# Otherwise we store the current number as key with its index as value
lookup[num]=cnt
enumerate() method adds a counter to an iterable and returns it in a form of enumerate object. This enumerate object can then be used directly in for loops or be converted into a list of tuples using list() method.
For e.g.
>>>list(enumerate("abc"))
Gives
[(0, 'a'), (1, 'b'), (2, 'c')]
For easy understanding, I'm commenting your program. Go through it, you'll surely understand.
class Solution:
def twoSum(self, nums, target):
# lookup is a dictionary that stores the number and its index
# e.g. '{7:1}'
# number 7 at index 1
lookup={}
# As explained above cnt and num will receive values one by one along with index.
for cnt, num in enumerate (nums):
# We look if the number required to be added into the 'num' is present in dictionary
if target-num in lookup:
# if value found in lookup then we return the current index along with the index of number found in lookup.
return lookup[target-num], cnt
# After every loop insert the current value and its index into the lookup dictionary.
lookup[num]=cnt
Hope, I answered your query in the way you wanted. Please comment below, if anything is left unanswered, I'll surely try to answer that as well.

How do you replace a list of 5 0's with the first 5 even numbers? (python)

even_numbers = [0] * 5
for i in range(1,11):
if i%2 ==0:
even_numbers[i]=i
I am getting the error 'list assignment index out of range', although i'm not quite sure what that means.
"List index out of range" basically means that you are trying to access an array index that doesn't exist.
In your code, your loop goes up to 10, and you are trying to assign a number to even_numbers[10], while your array only has 5 elements. Basically you're telling your program "give me the 10th element of this 5-element list", which does not make much sense. Your indices in this case only go from 0 to 4.
To fix your issue, try storing the current index in a variable:
even_numbers = [0] * 5
current_index = 0
for i in range(1,11):
if i%2 ==0:
even_numbers[current_index]=i
current_index += 1
Edit: Alternatively, why not loop through even elements only, using the step argument of the range() function?
even_numbers = [0] * 5
current_index = 0
#will increment 'i' 2 by 2, i.e. i will be 2, then 4, then 6, ...
for i in range(2,11, 2):
even_numbers[i/2]=i
current_index += 1
The message means that you are trying to access an element of the list which does not exist.
The list only has five elements with indices 0 to 4. Trying to assign a value to even_numbers[i], you will try to assign a value to all elements of the list in the range of 1 to 10. That's why you should change the indexing to even_numbers[i/2]
The simplest solution is to generate the list of even numbers in the first place.
even_numbers = list(range(1,11,2))
If, for some reason, you already have the list, it's doesn't really matter what the original contents are if you are just going to replace them.
for i, _ in enumerate(even_numbers):
even_numbers[i] = 2*i
or just even_numbers[:] = range(1, 11, 2)

Looping Through List Returns Negative Index

I'm solving a puzzle that takes in a list, loops through each index and sums the values to the left and to the right of the current index. If it finds an index at which the sum of the values to its left are equal to the sum of the values to its right, then return that index.
For example:
[1,2,3,4,3,2,1]
If I am at index 3 (value 4), we see that the sum of values of elements to its left and right are equal.
(1 + 2 + 3) = (3 + 2 + 1).
However, when the input is a list of negative values, it returns a negative index. This is my code:
def get_equal_sum(list):
for i in list:
if sum(list[:i]) == sum(list[i+1:]):
print i
list = [1,2,3,4,3,2,1]
get_equal_sum(list)
>>> 3
list = [-1,-2,-3,-4,-3,-2,-1]
get_equal_sum(list)
>>> -4
Why is it returning -4 and not 3?
Thank you!
When you do
for i in list:
if sum(list[:i]) == sum(list[i+1:]):
i is not the index of the list but the value. The fact that it doesn't crash with IndexError when you feed the slices with negative values is because negative indexing is supported in python (indexes from the end of the list) as long as absolute value is in range (which is the case here). That's probably why you missed that.
If you want indexes you have to use enumerate for instance:
for i,_ in enumerate(l):
if sum(l[:i]) == sum(l[i+1:]):
(and change list to l because list is the list type)
Note the i,_ notation to unpack index/value and discard the value which isn't needed here. You could also go with the classical:
for i in range(len(l)):
for i in list:
...
This goes through the values of list, not the index (hence you why you get -4), to go through index you must use xrange (or range for python 3) over the len(list)
for i in xrange(len(list)):
...
or use enumerate(list). enumerate returns a tuple of the index value pair on any iteratable object, so you would index over a list like this:
for index, value in enumerate(list):
...
In this situation index is likely your i. Additionally, you do not want to shadow names already used by python itself (ie list or max, or min abs etc...) this will overwrite those variables to be what you assign them to in your program. For example, list is no longer a function that can create a list from list(iterable), but is now what ever you assign it to, you can no longer use it the default python way. Here is a list of python 2.7 built function in names
Because -4 is at index -4. You can have negative indices in Python with index -1 being the last element in a list.

Find middle of a list

How would I find the exact middle of a python list?
aList = [1,2,3,4,5]
middle = findMiddle(aList)
print middle
This is just an example of a function that would be able to find the middle of any list, is this something you can do using list comprehension?
Edit: This is different than taking out the middle point because I would like to just print out the middle value, if the list is odd I would like to return both the middle values like the accepted answer. Not getting the median like the other question has asked and getting the average of the two values.
Something like this would do:
aList = [1,2,3,4,5]
#minus 1 because the first element is index 0
middleIndex = (len(aList) - 1)/2
print middleIndex
print aList[middleIndex]
Why would you use a list comprehension? A list comprehension only knows about any one member of a list at a time, so that would be an odd approach. Instead:
def findMiddle(input_list):
middle = float(len(input_list))/2
if middle % 2 != 0:
return input_list[int(middle - .5)]
else:
return (input_list[int(middle)], input_list[int(middle-1)])
This one should return the middle item in the list if it's an odd number list, or a tuple containing the middle two items if it's an even numbered list.
Edit:
Thinking some more about how one could do this with a list comprehension, just for fun. Came up with this:
[lis[i] for i in
range((len(lis)/2) - (1 if float(len(lis)) % 2 == 0 else 0), len(lis)/2+1)]
read as:
"Return an array containing the ith digit(s) of array lis, where i is/are the members of a range, which starts at the length of lis, divided by 2, from which we then subtract either 1 if the length of the list is even, or 0 if it is odd, and which ends at the length of lis, divided by 2, to which we add 1."
The start/end of range correspond to the index(es) we want to extract from lis, keeping in mind which arguments are inclusive/exclusive from the range() function in python.
If you know it's going to be an odd length list every time, you can tack on a [0] to the end there to get the actual single value (instead of an array containing a single value), but if it can or will be an even length list, and you want to return an array containing the two middle values OR an array of the single value, leave as is. :)
Take the length of the list, cut that in half and access whatever the list at that index point.
Are you expecting something like
def findMiddle(list):
l = len(list)
if l/2:
return (list[l/2-1]+list[l/2])/2.0
else:
return list[(l/2-1)/2]

Categories