I am trying to find the index value of some odd integers in a list. The program at its current stage only returns a new list containing only the odd integers.
image of my code
This program returns the values [3, 5, 7]. How would i be able to retrieve the index of these odd values instead? For example, [0, 1, 3, 5] for the list shown above.
I have tried "position = dataItem1.index()". I understand that i would need to input an index value within the index brackets.
you can use also use enumerate : it returns the index of the element and the element (also, in python you can loop directly over the elements of a list, no need of while loops). I also encourage the use of .append() to add an element to a list, this is clearly more efficient than concatenate two lists as you do:
l = [0, 3, 2, 3, 4, 7, 6]
def get_odds_index(l):
res = []
for idx, val in enumerate(l):
if val % 2 != 0:
res.append(idx)
return res
get_odds_index(l)
Instead of adding the element on that index in the odd list, just add index
Like this
def positionOfOdds(arr):
odds = []
length = len(arr)
index = 0
while index < length:
data = arr[index]
if data % 2 != 0:
odds.append(index)
index += 1
return odds
you already know the index, it is the loop variable
def positionOfOdds(arr):
odds = []
length = len(arr)
index = 0
while index < length:
data = arr[index]
if data % 2 != 0:
odds = odds + [index]
index += 1
return odds
You use an array called odds to store the odd numbers, to get the indexes you can create instead an array to store the indexes of the odd numbers, which I called odds_idxs. It should look something like this:
num_list = [0, 3, 2, 3, 4, 7, 6]
def position_of_odds(num_list):
odds_idxs = []
length = len(num_list)
index = 0
while index < length:
if num_list[index] % 2 != 0:
odds_idxs = odds_idxs + [index]
index = index + 1
return odds_idxs
I have a list of integers, and I want to add 1 to each integer in the list with every iteration of a while loop. More specifically, I want to perform this operation on the list's integers one by one (left to right) instead of all at once, and stop the loop as soon as the its conditional becomes False, even if that means stopping before the end of the list.
First, I tried the following:
def myfunction(someinput):
myintegerlist = [0, 0, 0]
while sum(myintegerlist) < someinput:
myintegerlist[0:] = [x+1 for x in myintegerlist[0:]]
return myintegerlist, sum(myintegerlist)
This doesn't do what I want, because it simultaneously adds 1 to all integers in the list. Thus if someinput = 4, it returns 6 as the sum and [2, 2, 2] as the list, whereas I would like it to stop at [2, 1, 1] before exceeding the input number. So I tried
while sum(myintegerlist) < someinput:
myintegerlist[indexplace] = [x+1 for x in myintegerlist[indexplace]]
indexplace += 1
This was just a guess, and throws "TypeError: 'int' object is not iterable". But I am stuck on how to get through the list items one by one and add 1 to them. Is there a good way to move incrementally through the list with each iteration? Or should I be trying something completely different?
Keep track of the index where you need to add the 1 during the while loop:
def myfunction(someinput):
myintegerlist = [0, 0, 0]
increment_index = 0 # next place to add 1
while sum(myintegerlist) < someinput:
myintegerlist[increment_index % len(myintegerlist)] += 1 # add 1 to the element, modulo length of the list to keep the index in range
increment_index += 1
return myintegerlist, sum(myintegerlist)
print(myfunction(4))
Result:
([2, 1, 1], 4)
Normally, in order to iterate over the values in a list you would just use
for value in myintegerlist:
# ...
but this doesn't allow you to directly change the value in the list.
You have to create a loop over the indices of the list.
for i in range(len(myintegerlist)):
value = myintegerlist[i]
In particular, by assigning to myintegerlist[i] you can change the values in the list.
for i in range(len(myintegerlist)):
value = myintegerlist[i]
myintegerlist[i] = new_value
Now you need one additional step, because you don't just want to iterate over each list index once, but possibly many times, until a condition is met. In order to keep the iteration going, you can use the cycle function from the itertools module.
from itertools import cycle
for i in cycle(range(len(myintegerlist))):
# i = 0, 1, 2, 0, 1, 2, 0, 1, ...
Now you can just add 1 to the value at the current list index and break the loop if the sum of the values has reached the desired amount:
for i in cycle(range(len(myintegerlist))):
if sum(myintegerlist) >= someinput:
break
myintegerlist[i] += 1
It is bad idea to start every time from 0. Too much meaningless iterations if someinput is a large number.
def get_els(sum_value: int, num_of_els: int = 3) -> tuple:
_list = [int(sum_value / num_of_els)] * num_of_els
if sum(_list) == sum_value:
return _list, sum_value
while True:
for idx in range(0, num_of_els):
_list[idx] += 1
if sum(_list) == sum_value:
return _list, sum_value
print(get_els(2))
print(get_els(4))
print(get_els(5))
print(get_els(10))
print(get_els(20))
Output:
([1, 1, 0], 2)
([2, 1, 1], 4)
([2, 2, 1], 5)
([4, 3, 3], 10)
([7, 7, 6], 20)
More over, if length of list is only 3 elements then loop is not necessary at all:
def get_els(sum_value: int) -> tuple:
_list = [int(sum_value / 3)] * 3
if sum_value % 3 == 0:
return _list, sum_value
if sum_value % 3 > 1:
_list[0] += 1
_list[1] += 1
else:
_list[0] += 1
return _list, sum_value
Hello there i'm trying sum_consecutives as the function name mention in array example:
[1,1,7,7,3] should return [2,14,3]
Problem:
Looks like my algorithm not working with all the array i get this result everytime [2,14]
the function:
def sum_consecutives(s):
sum = 0
X = []
for i in range(0,len(s)-1):
print( i)
if s[i] == s[i+1]:
sum += s[i]
else:
X.append(sum+s[i])
sum = 0
return X
Your algorithm won't work because you're iterating from index 0 until index len(s) - 1, excluding the last element since the range function is end-exclusive (range(0, 5) iterates from 0 to 4). You can iterate over all elements and introduce a new variable to store the last element:
def sum_consecutives(values):
result = []
# Stores the first consecutive element
last_elem = None
for curr_elem in values:
# If the last element is not initialized,
# initializes it and proceed with the iteration
if last_elem is None:
last_elem = curr_elem
continue
# If the current element is equal to the last
# element, push the sum to the result list
if last_elem == curr_elem:
result.append(last_elem + curr_elem)
# Otherwise, push both elements to the result list
else:
result.append(last_elem)
result.append(curr_elem)
# Reset the last element set
last_elem = None
# If there's an element not paired (i.e. not None),
# push its value to the result array
if last_elem is not None:
result.append(last_elem)
return result
Some tests:
assert sum_consecutives([1, 1, 7, 7, 3]) == [2, 14, 3]
assert sum_consecutives([1]) == [1]
assert sum_consecutives([1, 1]) == [2]
assert sum_consecutives([1, 2, 1]) == [1, 2, 1]
Also, avoid naming your variable sum, it'll shadow the sum built-in.
I am learning the basics of python, and trying to solve the above mentioned problem. However, I got stuck at this point: when I'm revising the code, everything seems OK to me, but I get an error:
print repr(string), numbers_in_lists(string) == result
File "/tmp/vmuser_tmqtokdyaa/main.py", line 25, in numbers_in_lists
while int(string[i]) <= prev:
IndexError: string index out of range
I did revise other threads with the same IndexError problem, but it didn't quite solve my situation here. Any clues? Thank you in advance.
Here goes the task:
Numbers in lists by SeanMc from forums
define a procedure that takes in a string of numbers from 1-9 and
outputs a list with the following parameters:
Every number in the string should be inserted into the list.
If a number x in the string is less than or equal
to the preceding number y, the number x should be inserted
into a sublist. Continue adding the following numbers to the
sublist until reaching a number z that
is greater than the number y.
Then add this number z to the normal list and continue.
def numbers_in_lists(string):
i=0
prev = 0
list = []
sublist = []
while i< len(string):
if int(string[i]) > prev:
list.append(string[i])
prev = int(string[i])
i +=1
else:
while int(string[i]) <= prev:
sublist.append(string[i])
i +=1
list.append(sublist)
sublist = []
return list
#testcases
string = '543987'
result = [5,[4,3],9,[8,7]]
print repr(string), numbers_in_lists(string) == result
string= '987654321'
result = [9,[8,7,6,5,4,3,2,1]]
print repr(string), numbers_in_lists(string) == result
string = '455532123266'
result = [4, 5, [5, 5, 3, 2, 1, 2, 3, 2], 6, [6]]
print repr(string), numbers_in_lists(string) == result
string = '123456789'
result = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print repr(string), numbers_in_lists(string) == result
That happens because in this inner while, where you get the error, you don't check if i < len(str) and you keep incrementing, checking only condition unrelated to this problem, ignoring if you've reached last character of a string or not.
I would change it to:
def numbers_in_lists(string):
i=0
prev = 0
list = []
sublist = []
while i< len(string):
if int(string[i]) > prev:
list.append(string[i])
prev = int(string[i])
i +=1
else:
while i< len(string) and int(string[i]) <= prev:
sublist.append(string[i])
i +=1
list.append(sublist)
sublist = []
return list
And I would consider using for loop instead of while in your case, but above works anyway.
This may seem like a simple question but when I attempted to implement selection sort in Python, I do not get a sorted list. Is there something wrong with my implementation? The subsetting may be a problem.
source = [4,2,1,10,5,3,100]
for i in range(len(source)):
mini = min(source[i:]) #find minimum element
min_index = source[i:].index(mini)-1 #find index of minimum element
source[i:][min_index]= source[i:][0] #replace element at min_index with first element
source[i:][0] = mini #replace first element with min element
print source
I think there were a couple issues.
First, when your do source[i:], I believe that returns a new array of the sub-elements requested and not part of the original array, thus if you modify it, your don't modify the original. Second, you were subtracting 1 from an index when you shouldn't.
source = [4,2,1,10,5,3,100]
for i in range(len(source)):
mini = min(source[i:]) #find minimum element
min_index = source[i:].index(mini) #find index of minimum element
source[i + min_index] = source[i] #replace element at min_index with first element
source[i] = mini #replace first element with min element
print source
This gives:
[1, 2, 3, 4, 5, 10, 100]
Here is how I would rewrite your code. Of course in Python I would just use list.sort() to sort a list, but here is a selection sort in Python.
We make a generator expression that returns tuples of (value, i) for a value and its index from the list. Then when min() evaluates to find minimum, it finds the lowest tuple value; since the value comes first in the tuple before the index, the value will be the important part, and min() will find the lowest value. (If there is a tie, min() will use the second part of the tuple, the index, as a tie-breaker. But for sort we don't care how ties are broken.)
Now, instead of searching through the sub-list to find the min value, and then searching through it again to figure out the index, we search through it once and get both min value and index.
But we don't actually care about the min value; we care about the index. So after min() is done, we just throw away the actual value but keep the index. Adjust the index to be correct in the whole list (not in the slice of the list) and then we can swap.
We use the standard Python idiom for swapping two values. Python will build a tuple object to be the intermediate, then unpack this tuple into the left-hand-side.
lst = [4,2,1,10,5,3,100]
for i_sortpos in range(len(lst)):
# Make a generator expression to return (value, i) pairs.
genexp = ((n, i) for i, n in enumerate(lst[i_sortpos:]))
# Use genexp with min() to find lowest and its index.
# (Use '_' for variable name for the actual value; we don't use it.)
_, i_min = min(genexp)
# Adjust index to be correct in full list.
i_min += i_sortpos
# Swap the number at i_sortpos with the lowest found.
lst[i_sortpos], lst[i_min] = lst[i_min], lst[i_sortpos]
print(lst)
EDIT: And here is a refinement of the above. A slice from a list actually allocates a new list; our code here doesn't need a new list, it just needs a convenient way to examine a sublist. The itertools module offers a function, islice(), that returns an iterator that iterates over a slice of a list. This avoids repeatedly creating and destroying lists as we examine each sublist.
I believe this is the most efficient way to do selection sort in Python. (You could get rid of the part where we bind the generator expression to the name genexp and save a few microseconds... just make the call to min() a long one-liner. But it's not really worth the loss of readability.)
import itertools as it
lst = [4,2,1,10,5,3,100]
for i_sortpos in range(len(lst)):
# Make a generator expression to return (value, i) pairs.
# Use it.islice() for to look at sublist.
genexp = ((n, i) for i, n in enumerate(it.islice(lst, i_sortpos, len(lst))))
# Use genexp with min() to find lowest and its index.
# (Use '_' for variable name for the actual value; we don't use it.)
_, i_min = min(genexp)
# Adjust index to be correct in full list.
i_min += i_sortpos
# Swap the number at i_sortpos with the lowest found.
lst[i_sortpos], lst[i_min] = lst[i_min], lst[i_sortpos]
print(lst)
def selectionSort(List_):
for i in range(len(List_)):`
#track the current smallest value
smallIndex = i
#loop from the current smallest value
for j in range(i+1,len(List_))
if List_[j] < List_[smallIndex]:
#if new value is less that our smallest value,change
#smallest value to this
smallIndex = j
if smallIndex != i:
#swap the values
List_[smallIndex],List_[i] = List_[i],List_[smallIndex]
#return sorted list
return List_
def ss(l):
for i in range(0,len(l)):
d=l.index(min(l[i:]))
c=l[i]
l[i]=min(l[i:])
l[d]=c
print(l) #it prints each step of selection sort
y=[10,9,1,5,0,6]
ss(y)
def selSort(L):
"""
Find the smallest element in the list and put it (swap it) in the first location,
Find the second element and put it (swap it) in the second locaiton, and so on.
"""
for i in range(len(L) - 1):
minIndx = i
minVal= L[i]
j = i + 1
while j < len(L):
if minVal > L[j]:
minIndx = j
minVal= L[j]
j += 1
temp = L[i]
L[i] = L[minIndx]
L[minIndx] = temp
return L
Call:
print( selSort([120,11,0,1,3,2,3,4,5,6,7,8,9,10]) )
Output
[0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 120]
s = [1,8,4,9,3,6,2]
for i in range(len(s)):
maxi = max(s[0:len(s)-i]) #find max element
tempi = s.index(maxi) # find index of max element
temp = s[len(s)-1-i] #assign last element as temp
s[len(s)-1-i] = maxi #put max element in last position
s[tempi] = temp # put the element initially at last in its new
print s
Find the position(first and last), swap the elements if last is lower.
nums = [4,2,1,10,5,3,100]
def sort(nums):
###Find the position and now first 0th element is sorted and rest is unsorted
#Second iteration first 2 element is sorted
for i in range(len(nums)-1):
miniposition = i
for j in range(i,len(nums)):
if nums[j] < nums[miniposition]:
miniposition = j
temp = nums[i]
nums[i] = nums[miniposition]
nums[miniposition] = temp
sort(nums)
print (nums)
First iteration(swapped 4 and 1)
[1, 2, 4, 10, 5, 3, 100]
[1, 2, 4, 10, 5, 3, 100]
[1, 2, 3, 10, 5, 4, 100]
[1, 2, 3, 4, 5, 10, 100]
[1, 2, 3, 4, 5, 10, 100]
[1, 2, 3, 4, 5, 10, 100]
Other way
nums = [4,2,1,10,5,3,100]
i = 0
while i<len(nums):
#smallest element in the sublist
smallest = min(nums[i:])
#index of smallest element
index_of_smallest = nums.index(smallest)
#swapping
nums[i],nums[index_of_smallest] = nums[index_of_smallest],nums[i]
i=i+1
print (nums)
a slight variation of the solution provided
def selection_sort(l):
i = 0
while i < len(l):
minium_value = min(l[i:]) # minium value at ith iteration
minium_value_index = l[i:].index(minium_value) # minium value index at i th iteration
if minium_value < l[i]: # if the current value already min, skip
l[i + minium_value_index] = l[i] # put current value in min value's index - swap 1
l[i] = minium_value # set current value with min value- swap 2
i += 1
return l
def selection_sort_min(): # sorting number
for i in range(len(num)-1):
current_min_index = i
for j in range(i+1,len(num)):
if num[j] < num[current_min_index] :
current_min_index = j
num[i],num[current_min_index] = num [current_min_index],num[i]
print(num)
num = [23,89,12,0,3,7,33]
selection_sort_min()
here is what I think is a good way to sort a list of numbers and I hope it helps:
list=[5,4,3,1,6,8,10,9]
listsorted=[]
for i in range(len(list)):
x=min(list)
list.remove(x)
listsorted.append(x)
print listsorted
and the result will be [1, 3, 4, 5, 6, 8, 9, 10]
I think the "accepted" answer here is unhelpful. If we look at e.g.
mini = min(source[i:]) #find minimum element
min_index = source[i:].index(mini) #find index of minimum element
not only is this inefficient in terms of creating list slices unnecessarily, but they are searched unnecessarily. It's reasonably concise but I don't think it's the best solution.
def Selection_Sort(Sarray):
length = len(Sarray)
i = 0
j = 0
for i in range(length):
j = i+1
for j in range(length):
if Sarray[i] < Sarray[j]
t = Sarray[i]
Sarray[i] = Sarray[j]
Sarray[j] = t
j = j+1
i = i+1
return Sarray
Code of select sort from MIT online course .
def selSort(L):
for i in range(len(L) - 1):
minIndx = i
minVal = L[i]
j = i+1
while j < len(L):
if minVal > L[j]:
minIndx = j
minVal = L[j]
j += 1
if minIndx != i:
temp = L[i]
L[i] = L[minIndx]
L[minIndx] = temp
def selectSort(L):
for i in range(len(L)):
print L
minIndex = i
minValue = L[i]
j = i + 1
while j < len(L):
if minValue > L[j]:
minIndex = j
minValue = L[j]
j +=1
temp = L[i]
L[i] = L[minIndex]
L[minIndex] = temp