Creating an empty list to have data assigned afterwards - python

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.

Related

Not access to while loop in

I am new in Python. In this try I think can not access elements in while loop!? How to reach all element in list, first, second, third,.... Please some help.
Here my code:
my_list=[5,8,9,10,22]
l=len(my_list)
# only for test output
print("My list has "+str(l)+" elements.")
while my_list[l-1]<1:
print (my_list[l-1])
if my_list[l-1]<1:
print(my_list[l-1])
l+=1 `
in your code, you are saying
while my_list[l-1] < 1:
but my_list[l-1] is equal to 10.
10 > 1 so it will never enter your loop.
If you want to print all the elements, you should use a for loop.
If you really want to use a while loop, what you can do is:
my_list = [5,8,9,10,22]
my_list_len = len(my_list)
i = 0
while i < my_list_len:
print(mylist[i])
i+=1
this is an example, and there is many other ways to do that.

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

Skip an iteration while looping through a list - 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

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.

Python iterator question

I have this list:
names = ['john','Jonh','james','James','Jardel']
I want loop over the list and handle consecutive names with a case insensitive match in the same iteration. So in the first iteration I would do something with'john' and 'John' and I want the next iteration to start at 'james'.
I can't think of a way to do this using Python's for loop, any suggestions?
This would be one for itertools.groupby, which groups consecutive equal elements from a list or other iterable. you can specify a function to do the comparison, so that, in your case, the same name in different cases can still be counted as the same thing.
for k, g in itertools.groupby(names, lambda s: s.lower()):
# Example: in the first iteration:
# k = "john"
# g = an iterator over ["john", "John"]
# Process them as you like
names = ['john','John','james','James']
for name, capitalized_name in zip(names[::2], names[1::2]):
print name, capitalized_name
Note that you need an even amount of items for this to work properly.
Or (maybe better; hard to tell with little context) use a set to filter the list to contain only unique names (note that this loses order):
>>> names = ['john','John','james','James','Jardel']
>>> unique_names = set([x.lower() for x in names])
>>> for unique_name in unique_names:
... print unique_name
...
jardel
james
john
You could just use a while loop:
i = 0
while i < len(names):
# compare names[i] with names[i + 1]
i = i + 2 # or + 1 if names not equal, for example
Or are you looking for something a bit more involved?
As you iterate thru the loop, you could try keeping track of the previous name in the list. At the same time, when you're going to store the names, you can make a call to lower() or capitalize() to make the formatting of each name consistent so that you can compare them easier.
e.g.
first = True
prev= ""
for name in names:
if first: #First iteration
prev = name.lower() #Need to get the first elem
do_something_to(curr)
first = False
else:
if prev == name.lower():
print "do nothing"
else:
do_something_to(curr)
prev = name.lower()
May not be the most efficient, but works.
My $0.02:
def byPairs(li):
for i in xrange(1, len(li), 2):
yield (li[i-1], li[i])
for a,b in byPairs(names):
if a.lower()==b.lower():
doSomething(a,b)
I'm not sure I understood the question exactly; what are you trying to accomplish?

Categories

Resources