Controlling the flow of for loop in python - python

I'm trying to solve a musical chairs problem. The list_of_people is the list which contains the position of the people in the circle. The steps variable is the length of the song. So at each steps an element from list_of_people. At the end there should be only one element.I'm trying to solve this by using a simple for loop. I am deleting the elements in the loop at each steps that is at a count. I have two requirements: 1.)When I delete an element I want to step back one position in the loop from my current position. So, when I delete, I set the integer to the previous element, so the next time it should start from that position. But that's not working
2.) When the last element is reached i want to restart the for loop from the first position.
I know there is a provision in python itertools.cycle for cyclic iteration, but the problem in that is the len() function is not available and i'm breaking my for loop by checking the length of list_of_people
count=0
list_of_people = list(range(1,inputlength+1))
for integer in list_of_people:
if count==steps:
print("Element removed: "+str(integer))
#Getting the previous index
previous = list_of_people.index(integer)-1;
#deleting the current element
del list_of_people[list_of_people.index(integer)]
#Setting the index to previous element, THIS IS NOT WORKING!
#Need some help here!!!!!
integer = list_of_people[previous]
count=0
if len(list_of_people) < 2:#This is the breaking condition
break
#I need some help here!!!
#I need to restart the for loop from the first position
if list_of_people.index(integer)==len(list_of_people)-1:
#Set the loop index to zero
count+=1
print("The remaining element: "+str(list_of_people[0]))
Can anyone please help me on this? If there are any mistakes in the code, please forgive me I'm new to python.

It is extremely unwise to try to delete things from a list while you're iterating over it. Instead, build a new list, for example with a list comprehension:
list_of_people = [p for i, p in enumerate(list_of_people) if (i + 1) % steps]
An quick example:
>>> people = range(10)
>>> [p for i, p in enumerate(people, 1) if i % 3]
[0, 1, 3, 4, 6, 7, 9]
Based on your clarifying comments, I think what you want is simply:
def musical_chairs(people, steps):
index = 0
people = list(people)
while len(people) > 1:
index = (index + steps) % len(people)
del people[index]
index -= 1
return people
Demo:
>>> musical_chairs(range(1, 11), 4)
[6]

Related

Python Find the mean school assignment - What is a loop?

I have been working on this assignment for about 2 weeks and have nothing done. I am a starter at coding and my teacher is really not helping me with it. She redirects me to her videos that I have to learn from every time and will not directly tell or help me on how I can do it. Here are the instructions to the assignment (said in a video, but made it into text.
Find the mean
Create a program that finds the mean of a list of numbers.
Iterate through it, and instead of printing each item, you want to add them together.
Create a new variable inside of that, that takes the grand total when you add things together,
And then you have to divide it by the length of your array, for python/java script you’ll need to use the method that lets you know the length of your list.
Bonus point for kids who can find the median, to do that you need to sort your list and then you need to remove items from the right and the left until you only have one left
All you’re doing is you need to create a variable that is your list
Create another variable that is a empty one at the moment and be a number
Iterate through your list and add each of the numbers to the variable you created
Then divide the number by the number of items that you had in the list.
Here's what I've done so far.
num = [1, 2, 3, 4, 5, 6];
total = 0;
total = (num[0] + total)
total = (num[1] + total)
total = (num[2] + total)
total = (num[3] + total)
total = (num[4] + total)
total = (num[5] + total)
print(total)
However, she tells me I need to shorten down the total = (num[_] + total) parts into a loop. Here is how she is telling me to do a loop in one of her videos.
for x in ____: print(x)
or
for x in range(len(___)): print (x+1, ____[x])
there is also
while i < len(___):
print(___[i])
i = i + 1
I really don't understand how to do this so explain it like I'm a total noob.
First of all, loops in python are of two types.
while: a while loop executes the code in a body until a condition is true. For example:
i = 0
while(i < 5):
i = i + 1
executes i = i + 1 until i < 5 is true, meaning that when i will be equal to 5 the loop will terminate because its condition becomes false.
for: a for loop in python iterates over the items of any sequence, from the first to the last, and execute its body at each iteration.
Note: in both cases, by loop body I mean the indented code, in the example above the body is i = i + 5.
Iterating over a list. You can iterate over a list:
Using an index
As each position of the array is indexed with a positive number from 0 to the length of the array minus 1, you can access the positions of the array with an incremental index. So, for example:
i = 0
while i < len(arr):
print(arr[i])
i = i + 1
will access arr[0] in the first iteration, arr[1] in the second iteration and so on, up to arr[len(arr)-1] in the last iteration. Then, when i is further incremented, i = len(arr) and so the condition in the while loop (i < arr[i]) becomes false. So the loop is broken.
Using an iterator
I won't go in the details of how an iterator works under the surface since it may be too much to absorb for a beginner. However, what matters to you is the following. In Python you can use an iterator to write the condition of a for loop, as your teacher showed you in the example:
for x in arr:
print(x)
An iterator is intuitively an object that iterates over something that has the characteristic of being "iterable". Lists are not the only iterable elements in python, however they are probably the most important to know. Using an iterator on a list allows you to access in order all the elements of the list. The value of the element of the list is stored in the variable x at each iteration. Therefore:
iter 1: x = arr[0]
iter 2: x = arr[1]
...
iter len(arr)-1: x = arr[len(arr)-1]
Once all the elements of the list are accessed, the loop terminates.
Note: in python, the function range(n) creates an "iterable" from 0 to n-1, so the for loop
for i in range(len(arr)):
print(arr[i])
uses an iterator to create the sequence of values stored in i and then i is in turn used on the array arr to access its elements positionally.
Summing the elements. If you understand what I explained to you, it should be straightforward to write a loop to sum all the elements of a list. You initialize a variable sum=0 before the loop. Then, you add the element accessed as we saw above at each iteration to the variable sum. It will be something like:
sum = 0
for x in arr:
sum = sum + x
I will let you write an equivalent code with the other two methods I showed you and do the other points of the assignment by yourself. I am sure that once you'll understand how it works you'll be fine. I hope to have answered your question.
She wants you to loop through the list.
Python is really nice makes this easier than other languages.
I have an example below that is close to what you need but I do not want to do your homework for you.
listName = [4,8,4,7,84]
for currentListValue in listName:
#Do your calculating here...
#Example: tempVar = tempVar + (currentListValue * 2)
as mentioned in the comments w3schools is a good reference for python.

How do I check every element in an appended text in python

I am doing the Euler project questions and the question I am on right now is least common multiple. Now I can go the simple route and get the factors and then find the number that way, but I want to make my life hard.
This is the code I have so far in Python:
i = 0
j = 0
count = []
for i in range (1,10):
for j in range(1,11):
k = i%j
count.append(k)
print(count)
Now when I print this out I get an array and every time I goes through the loop, the previous information is appended on with it. How can I make it so that the previous information is not appended?
Second once I get that information how can I look at each value in the array and only print out those elements that are equal to 0? I feel like I have to use the all() function but for some reason I just dont get how to use it.
Any and all help is appreciated.
For your first question, you should know the scope of variable. Just define the variable count inside the outer loop and before the inner loop starts.
You can try this if you want nothing but zero elements.
print [element for element in count if element == 0]
If I understand your question right the answer for your question is like this.
i = 0
j = 0
for i in range (1,10):
# Resetting so that count will not have previous values
count = []
for j in range(1,11):
k = i%j
count.append(k)
# printing all the indexes where the value is '0'
print([index for index, item in enumerate(count) if item == 0])
You know your range of extern loop so you can just write your code in this way :
count = []
for i in range (1,10):
for j in range(1,11):
k = i%j
if(i == 9):
count.append(k)
print(count)
print("Without 0:")
print([x for x in count if x is not 0])

function that checks the length of the cycle

Hey guys i have the function, but it gives me error when I test it.
Does anyone have any Idea on how to fix it
This is my exercise. Please read through.
Write a function cycleLength(array), which returns the number of students that form a loop, given that you start by talking to the left-most one. The input array is a list of non-negative integers, such that array[m] is the number of the student to whom student m redirects. No student redirects to himself. The left-most student is number 0, the next is number 1, and so on. Each element in the list will be in the range [0, n-1] where n is the length of the list.
For example, suppose the list was [1, 3, 0, 1]. Then student 0 redirects to student 1, who redirects to student 3, who redirects back to student 1. There is a loop of two students: 1, 3. Thus the answer would be 2. Note that even though you started with student 0, he is not part of the loop.
Here is my function:
def cycleLength(m):
lst = []
i = 0
while i not in lst:
lst.append(i)
i = int(m[i])
b = len(lst) - lst.index(i)
return b
You almost got it right.
>>> def cycleLength(students):
... seen = []
... current = 0
... # Run till we have seen all the students
... while len(seen) != len(students):
... # If the current index has been seen already
... if current in seen:
... return len(seen) - seen.index(current)
... seen.append(current)
... current = students[current]
...
>>> assert(cycleLength([1, 3, 0, 1]) == 2)
>>> assert(cycleLength([1, 3, 0, 2]) is None)
This will take care of the case where there is no loop as well.
def cycleLength(m):
lst = []
for x in m:
if x in lst:
return len(lst) - lst.index(x)
lst.append(x)
return -1
Explanation:
you should loop while the element at index i m[i] is not already in lst - what you where doing is looking for the index in the list instead of "the element at index"
Same as previous point, you should append to lst the elements - not the index of the elements - otherwise you won't find any such "duplicate" elements - since the index should just increase.
Regards the last point - the index should keep increasing on each iteration
And last, the length of the cycle is between the first time that an element appears to the next time that you iterate the same element. And it's not necessarily from the beginning of the list.
Correction:
Previous version of the code had bugs, a simpler version of the same idea, and which is also bug-free (I believe), is posted here. -1 represents "no cycles found".

What is the role of the for loop in this sorting function?

I'm looking at this function while I try to learn different ways data is sorted, and I understand the main concept of it all including the while loop. The only thing I don't get is the role of the for loop on the first line of the function. Isn't the while loop doing the iterating and comparisons on the list? I tried taking the for loop out and as assumed the program failed to sort. It ran without error but simply returned the same list, unchanged. I guess I must not completely understand the sort if this doesn't make sense to me. So my question is: What is the role of the for loop in this sort function and what is it affecting each time through?
def selSort(L):
for i in range(len(L) - 1):
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
return L
Q = [2, 8, 5, 9, 1, 15, 3, 7]
selSort(Q)
print Q
Output:
[1, 2, 3, 5, 7, 8, 9, 15]
[What is] the role of the for loop on the first line of the function. Isn't the while loop doing the iterating and comparisons on the list?
The while loop finds the right element for one specific position in the list, and the for loop repeats the search for every position (thereby sorting the list).
And all the if condition does is find the smallest element of those that haven't yet been placed. Thus on the first iteration of the for loop the algorithm will find the smallest element; on the second iteration, the second smallest; and so on.
Selection sort "selects" the smallest element in a dataset and puts it at the beginning, then repeats on the rest of the list with the smallest element removed. Worded differently, at each step of selection sort, we move along each spot in the list and figure out what number should be at that spot in the list.
If we have the list 7 5 2 3 4 6 9 1 8, then our first step would be to swap a 1 into the first place, a 2 into the second place, and so on. We don't have to worry about the very last spot in the list, because if we've taken everything else and put it in the right place, the last element will be in the right place because it's the only one left.
With this code, although it's not done as clearly, the outer for loop goes through every spot in the list, minus the last one (len(L) - 1). Once we go through the code inside the loop once, we'll have put the right number in the first spot, then we go again to try and fill the second spot, etc. Because we've put everything in the correct place for all of the spots before this one, we can assume that the correct thing in this spot will be the smallest item between this position and the end of the list, so, the while loop helps look for it. Then, we swap the two items.
This code is kind of messy, and it may make more sense if we reword the inner while loop to be a for loop:
def selSort(L):
for i in range(len(L) - 1):
minIndex = i
minValue = L[i]
for j in range(i + 1, len(L)):
if minValue > L[j]:
minIndex = j
minValue = L[j]
temp = L[i]
L[i] = L[minIndex]
L[minIndex] = temp
return L

List index out of range while counting Python

I have a little problem - I need to iterate through a list of lists (lines in a file) and count how many times the lines begin with six or seven. It was no problem, but I also need to remove the items which repeat themselves, e.g. if I have this: [6,6,7,7,6], I need to do this out of it: [6,7,6] - it is the number of switches that counts. But somehow the list index is always out of range. Why?
Thank you!
def number_of_switches(list):
counter = []
for element in li:
if int(element[0]) == 6 or int(element[0]) == 7: counter.append(element[0])
else: pass
i = 0
for i in (0, len(counter)):
if counter[i] == counter[i+1]: counter.remove(counter[i+1])
print 'number of switches is', len(counter)-1 #the first number doesn't count as switch, hence '-1'
for i in (0, len(counter)) only iterates over two elements: 0, and the length of counter. It does not count up from 0 to the length. For that you need range:
for i in range(len(counter))
However, you should not do that either. Think about what happens each time you remove an element: the list is now one shorter, but you are iterating until the end of the original list. So you will quickly get an IndexError. You need to append the non-matching elements to a new list, rather than removing from the current one.
When you write:
for i in (0, len(counter)):
That means for in those two values: 0 and len(counter) and, len(counter) is the index out of range.
I think you meant:
for i in range(0, len(counter)):
You should be doing for i in range(len(counter)): and also if counter[i] == counter[i+1]: will give an error in this range. You need to handle the end case.
This might be a better solution:
def number_of_switches(list):
counter = []
prev = li[0]
for element in range(1, len(li)):
if int(li[element][0]) != prev:
count.append(int(li[element][0]))
print 'number of switches is', len(counter)-1 #the first number doesn't count as switch, hence '-1'

Categories