Skip an iteration while looping through a list - Python - python

Is there a way to skip the first iteration in this for-loop, so that I can put a for-loop inside a for-loop in order to compare the first element in the list with the rest of them.
from collections import Counter
vowelCounter = Counter()
vowelList = {'a','e','i','o','u'}
userString = input("Enter a string ")
displayed = False
for letter in userString:
letter = letter.lower()
if letter in vowelList:
vowelCounter[letter] +=1
for vowelCount1 in vowelCounter.items():
char, count = vowelCount1
for vowelCount2 in vowelCounter.items(STARTING AT 2)
char2, count2 = vowelCount2
if count > count2 : CONDITION
How would the syntax go for this? I only need to do a 5 deep For-loop. So the next would Start at 3, then start at 4, then 5, the the correct print statement depending on the condition.
Thanks

You could do:
for vowelCount2 in vowelCounter.items()[1:]:
This will give you all the elements of vowelCounter.items() except the first one.
The [1:] means you're slicing the list and it means: start at index 1 instead of at index 0. As such you're excluding the first element from the list.
If you want the index to depend on the previous loop you can do:
for i, vowelCount1 in enumerate(vowelCounter.items()):
# ...
for vowelCount2 in vowelCounter.items()[i:]:
# ...
This means you're specifying i as the starting index and it depends on the index of vowelCount1. The function enumerate(mylist) gives you an index and an element of the list each time as you're iterating over mylist.

It looks like what you want is to compare each count to every other count. While you can do what you suggested, a more succinct way might be to use itertools.combinations:
for v1,v2 in itertools.combinations(vowelCounter, 2):
if vowelCounter[v1] > vowelCounter[v2]:
# ...
This will iterate over all pairs of vowels for comparison. Doing it this way, you may also want to check if vowelCounter[v2] > vowelCounter[v1] as you won't see these two again (this goes for this method or the nested for loop method). Or, you can use the itertools.permutations function with the same arguments and just one check would suffice.

To skip an iteration you can use the continue keyword eg:
list = [1,2,3,4,5,6,7,8,9,10]
for value in list:
if value == list[0]:
continue
print(value)
Would give you:
2
3
4
5
6
7
8
9
10
I hope this answers your question.

Slicing a list with [1:] as suggested by a few others creates a new array. It is faster and more economic to use a slice iterator with itertools.islice()
from itertools import islice
for car in islice(cars, 1, None):
# do something

Related

for loop while decrementing the size of the list

so I have a list of 5 or fewer elements and the elements are just integers from 0-9 and the elements are randomly assigned and its possible for the list to have 5 zeros or 5 ones etc, and I have the following function to check if there is a zero in the list. this will return the index of the first zero it finds. just ignore the .getValue()
def check0(self):
'''
check for the index of the first card with value 0 in hand
:return:
'''
index = 0
found = False
while not found and index<len(self.hand):
if self.hand[index].getValue() == 0:
found = True
index += 1
if not found:
index = -1
return index
but the problem is that it always returns the first zero it finds in the list. in another class I am using this function to check if the hand has any zeros.
I need to write a for loop or some other loop that will traverse the list hand and tell me if all the elements in the hand are zeros.
so the only solution I can think of for this problem is to traverse the list once and when the first zero is found increment the counter and then traverse the list again this time excluding the zero that had already been found.
for example:
I have the list
[0,0,0,0,0]
in the first traversal, the check0() method will return the index 0 for the first zero but then I traverse the list again this time excluding the first zero and repeating that until I reach the last element.
I was thinking something like this:
def find_zeros():
counter = 0
for I in some_list(0,len(some_list),-1):
if I.check0() != -1:
counter += 1
if counter == len(some_list):
return True
return False
can anyone help me with this issue?
let me know if anything is unclear
also I'm not allowed to import anything and time complexity isn't an issue
"I need to write a for loop or some other loop that will traverse the list hand and tell me if all the elements in the hand are zeros." (OP)
Well, to check if all elements in your list are zero you could use count:
lst1 = [0,0,0,0,0]
print(len(lst1) == lst1.count(0))
Or maybe list comprehension:
lst1 = [0,0,0,0,0]
print(lst1 == [nr for nr in lst1 if nr == 0])
probably better written using all like:
lst1 = [0,0,0,0,0]
print(all(i==0 for i in lst1))
Or maybe create a second list the same size:
lst1 = [0,0,0,0,0]
print(lst1 == [0]*len(lst1))
You can use enumerate for this type of problem.
for index, ch in enumerate(list_name):
print(i, ch)
This will give you the index of each and every character in the list.
You can use an 'if' statement later to check if 'ch' is a zero.
Hope it helped.
listt=[1,0,2,0,1]
for i in range(len(listt)):
if listt[i]==0:
print(i)
break #if you want to find first occurence
To check all ekements are 0,
if len(set(listt))==1 and listt[0]==0:
print("All index have 0 ")
You could define the function like this:
def check0(self):
index = (self.hand+[0]).index(0)
return -1 if not any(self.hand) else index

Removing n multiple items from a list

Question
I want to remove items from a list such that I keep the first n items, and remove the next 2n items.
For example
for n=8, I want to keep the first 8, remove the next 16 and repeat this as necessary:
a = range(48)
Which I want to become
[0,1,2,3,4,5,6,7,24,25,26,27,28,29,30,31]
This is to pick out the first 8 hours of a day, and run a function on each hour.
I've found it hard to phrase this in search queries so the answer is probably simple but I've had no luck!
You could just use a comprehension list:
[ a[i] for i in range(len(a)) if (i % 24 < 8) ]
The above only create a new list. If you want to edit the list in place, you must explicitely delete unwanted elements, starting from the end to avoid changing indexes:
for i in range(len(a) - 1, 0, -1):
if i % 24 >= 8:
del a[i]
def hours(n):
items = [x for x in range(49)]
del items[n:n*3]
print(items)
hours(8)
Depending on how new you are you might have a hard time understanding this code, so I will try to explain a little:
We start by creating a function which takes a parameter n which, for test purposes, we will be using 8 then we use a list comprehension to generate all our numbers (0, 48) and then delete the unneeded elements using the del statement, we are deleting from the nth to the n*3 element in the list. For example, if n were to be passed as 9 our use of the del statement could be translated as: del [9:27].
Hope this makes sense.
This should be quite easy to understand
a = range(48)
n=8
result=[]
while a:
result+= a[:n]
a=a[n*3:]
print result

Loop in a list (Python v3) beginner

I am stuck in making a loop that will eliminate the values(from the alist) that are below average.
Thanks for the help.
a=input("Enter a list of values separated by a coma : ")
alist=eval(a)
print("the list is : ",alist)
average = sum(alist)/len(alist)
print("the average is : ",average)
for i in alist:
if alist[i]<average:
alist.remove[i]
You are almost there. Instead of removing elements, select elements you want to retain instead:
alist = [a for a in alist if a>=average]
Your mistake here is that for i in alist: is iterating over list elements themselves, not indexes, so alist[i] is throwing an error (or returning nonsense).
For the "loop" you can use a filter and a lambda function.
above_average = list(filter(lambda x: x >= average, alist))
For the rest of your code, I suggest you clean it up to something which is safer (use of eval is very bad)
import ast
user_string = raw_input('input a list of numbers separated by a commas: ')
alist = list(ast.literal_eval(user_string)))
So, in all, I would write your code as something like this:
import ast
user_string = raw_input('input a list of numbers separated by a commas: ')
numbers = list(ast.literal_eval(user_string)))
average = sum(numbers)/len(numbers)
print('The numbers: {}'.format(numbers))
print('The average: {}'.format(average))
above_average = list(filter(lambda x: x >= average, numbers))
# now do what you want with the above_average numbers.
Other answers tell you how to do it. I'll tell you why it doesn't work:
You iterate over the list and, at the same time, modify it.
This leads to items being missed during the iteration.
Why?
Internally, the iteration works via an index to the list. So it is the same as doing
idx = 0
while True:
try:
i = alist[idx]
except IndexError:
break
idx += 1
if alist[i] < average:
alist.remove(i)
What happens if you are at the element #3, go to the next one and then remove #3? Right, the indexes of the remaining ones move down and you are pointing to the one which formerly was #5. The old #4 is skipped at this test.
(BTW, I don't know if you noticed, I have replaced your [] behind .remove with ().)
You are mixing two ways of iterating a list: By index, and by element. In your loop, i is not the index, but the element of the list itself, thus alist[i] won't work.
If you use the for x in somelist loop, then x is the element itself, not the index of the element. For iterating over the indices, you can use for i in range(len(somelist)), or you could use for i, x in enumerate(somelist) to loop over tuples of index and element.
Also note that removing elements from a list or other kinds of collections while you are looping them generally is a bad idea. Better create a copy of the list.
for x in list(alist): # creates a copy of alist
if x < average: # remember: x is the element itselt
alist.remove(x) # remove element x from list
But the way you do it (with eval of a comma-separated string of numbers), alist is a tuple, not a list, and thus has no remove method at all. Thus you either have to convert it to a list before (alist = list(eval(a)), or use one of the approaches given in the other answers, creating a new list using list comprehension or filter and retaining the "good" elements.
As a general principle for asking StackOverflow questions like this, you should always include example input and output -- show what happens, and what you expect to happen.
In this case, I believe there are two three problems with your code:
Edit: Third, but possibly most importantly, look at glglgl's answer. If you implement the two fixes I describe below, you'll still have one problem: your code won't necessarily remove all the items you want to remove, because it'll skip over some items.
First, you say alist[i], which grabs the element of alist at index i. But saying for i in alist makes i be successive elements in the list already. Example:
mylist = [1, 2, 4]
for i in mylist:
print(i)
Would give you the output:
1
2
4
If you instead said this (which is like what you wrote)
mylist = [1, 2, 4]
for i in mylist:
print(mylist[i])
It wouldn't work as you'd expect, because you'd get the element at index 1, the element at index 2, and then try to get the element at index 4, but that wouldn't exist. You'll get something like this:
2
4
IndexError: list index out of range
Second, your syntax for removing an element is wrong. You should use alist.remove(i) instead of alist.remove[i]. You want to call a function, so you use parentheses. The square brackets are for indexing and slicing.

Count the number of occurrences of a given item in a (sorted) list?

I'm asked to create a method that returns the number of occurrences of a given item in a list. I know how to write code to find a specific item, but how can I code it to where it counts the number of occurrences of a random item.
For example if I have a list [4, 6 4, 3, 6, 4, 9] and I type something like
s1.count(4), it should return 3 or s1.count(6) should return 2.
I'm not allowed to use and built-in functions though.
In a recent assignment, I was asked to count the number of occurrences that sub string "ou" appeared in a given string, and I coded it
if len(astr) < 2:
return 0
else:
return (astr[:2] == "ou")+ count_pattern(astr[1:])
Would something like this work??
def count(self, item):
num=0
for i in self.s_list:
if i in self.s_list:
num[i] +=1
def __str__(self):
return str(self.s_list)
If this list is already sorted, the "most efficient" method -- in terms of Big-O -- would be to perform a binary search with a count-forward/count-backward if the value was found.
However, for an unsorted list as in the example, then the only way to count the occurrences is to go through each item in turn (or sort it first ;-). Here is some pseudo-code, note that it is simpler than the code presented in the original post (there is no if x in list or count[x]):
set count to 0
for each element in the list:
if the element is what we are looking for:
add one to count
Happy coding.
If I told you to count the number of fours in the following list, how would you do it?
1 4 2 4 3 8 2 1 4 2 4 9 7 4
You would start by remembering no fours yet, and add 1 for each element that equals 4. To traverse a list, you can use a for statement. Given an element of the list el, you can check whether it is four like this:
if el == 4:
# TODO: Add 1 to the counter here
In response to your edit:
You're currently testing if i in self.s_list:, which doesn't make any sense since i is an element of the list and therefore always present in it.
When adding to a number, you simply write num += 1. Brackets are only necessary if you want to access the values of a list or dictionary.
Also, don't forget to return num at the end of the function so that somebody calling it gets the result back.
Actually the most efficient method in terms of Big-O would be O(log n). #pst's method would result in O(log n + s) which could become linear if the array is made up of equal elements.
The way to achieve O(log n) would be to use 2 binary searches (which gives O(2log n), but we discard constants, so it is still O(log n)) that are modified to not have an equality test, therefore making all searches unsuccessful. However, on an unsuccessful search (low > high) we return low.
In the first search, if the middle is greater than your search term, recurse into the higher part of the array, else recurse into the lower part. In the second search, reverse the binary comparison.
The first search yields the right boundary of the equal element and the second search yields the left boundary. Simply subtract to get the amount of occurrences.
Based on algorithm described in Skiena.
This seems like a homework... anyways. Try list.count(item). That should do the job.
Third or fourth element here:
http://docs.python.org/tutorial/datastructures.html
Edit:
try something else like:
bukket = dict()
for elem in astr:
if elem not in bukket.keys():
bukket[elem] = 1
else:
bukket[elem] += 1
You can now get all the elements in the list with dict.keys() as list and the corresponding occurences with dict[key].
So you can test it:
import random
l = []
for i in range(0,200):
l.append(random.randint(0,20))
print l
l.sort()
print l
bukket = dict()
for elem in l:
if elem not in bukket.keys():
bukket[elem] = 1
else:
bukket[elem] += 1
print bukket

Creating an empty list to have data assigned afterwards

Lets say that I want to create a list of names
listOfNames = []
Then I have a while loop such as
count = 0
while listOfNames[count] < 10:
nameList[count] = raw_input("Enter a name: ")
count += 1
Python says that the list index is out of range, but the list index should be at 0, correct?
How do add to the list each time the while loop is ran? I'm assuming something is wrong with my list assignment.
An empty list doesn't have any index yet, it's an empty list! If you want to fill it, you have to do something like this :
while count < 10:
nameList.append(raw_input("Enter a name: "))
count += 1
This way, your condition will be evaluated and with the append method, you will be able to add new items in your list.
There are a few advanced tricks to do this easily, but considering your level, I think it's better that you understand this code before moving on.
Most idiomatic is to use a list comprehension:
namelist = [raw_input("Enter a name: ") for i in range(10)]
(or use _ for i, although I personally wouldn't)
This has the advantage of creating the list on the fly, while having to use neither the append() method nor explicit indexing.
count = 0
while listOfNames[count] < 10:
nameList.append(raw_input("Enter a name: "))
count += 1
Use append for quick n easy...
Alternatively:
nameList[len(nameList):] = [raw_input("Enter a name: ")]
Edit: Did you mean listOfNames to be appended as opposed to nameList?
Your list assignment is right, your problem is with your use of indexes which do not yet exist.
count = 0
while listOfNames[count] < 10:
nameList[count] = raw_input("Enter a name: ")
count += 1
I'm fairly sure this code doesn't do what you intend. What this code is doing is checking the first through tenth elements of listOfNames for a number which is less than 10, but since its an empty list there is no element with index 0, or any other index for that matter hence your list index out of range exceptions.
The following will work as you intend:
count = 0
while len(listOfNames) < 10: # Keep going until the list has 10 elements
nameList.append(raw_input("Enter a name: "))
count += 1
However I'd suggest using the following which does exactly the same thing but should be more efficient as well as being more aesthetically pleasing:
for _ in range(10):
listOfNames.append(raw_input("Enter a name:"))
Note the use of append instead of an index reference. This will add the new element on to the end of the list whereas using the index as you were trying to do will fail since to assign to and index there has to be an element present in the first place.

Categories

Resources