List index out of range while counting Python - 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'

Related

Check the duplicate element in an array using set in python

Scan and check the numbers in an array if it is repeated, if true print yes, else print no
So what I'm trying to do is convert them into a set (and list)
a = [int(v) for v in input().split()]
b = set(a)
and check if the occurrence of an element in list a is equal to that is set b, but currently, there's no such function to count the occurrence in set b, isn't it? I'm dumb so pls help
for i in range(len(a)):
if a.count(a[i]) == ..occurrence in set b..:
print("NO")
else:
print("YES")
example input:
1 2 3 2 3 4
output:
NO
NO
NO
YES
YES
NO
Given the problem description you need a code that identifies if an item of a list appears in it more than once. Here's one way you can do it,
from collections import Counter
# Input list with duplicates
numbers = [1, 2, 3, 2, 3, 4]
# Count of each list element
counted_numbers = Counter(numbers)
# Chech occurrence of each list element
for el in numbers:
if counted_numbers[el] > 1:
print('YES')
else:
print('NO')
The code uses Counter to create a dictionary with number of occurrences of each list element. In other words, counted_numbers are a dictionary where the keys are unique elements of the list numbers and the values are the number of times they appear in the list.
The second part of the code loops through the original list and checks how many times it appears as reported by Counter. If its more than one, it prints YES.
Temporary note: the output is different than in your example, let me know if this is not what you're looking for.
I think this is what you're looking for:
for i in range(len(a)):
if a[i] in a[:i]:
print("YES")
else:
print("NO")
If the number at index is appeared on the left hand side of the current index, it is printed YES, otherwise NO.
count = set()
for num in nums:
if num in count:
print("YES")
else:
print("NO")
count.add(num)

Looping through a list and finding when numbers stop increasing at the same rate

I have a list of numbers that initially increase at the same rate. For example:
[0,3,6,9,12,15,18...]
However, when reaching a certain point in the list, the increase in value actually increases.
[0,3,6,9,12,15,18...150,156,162,168,174...240]
I want to loop over this list and create two new lists. One where the number increases by 3, and one when the numbers begin to increase by 6. However, I am not sure how exactly to write the code that detects when this change occurs.
Expected result:
[0,3,6,9,12,15,18...,147]
[150,156,162,168,174...240]
def splitList(list):
if(len(list) < 2):
return [], []
listX = []
listY = []
dif = list[1] - list[0]
for e in list:
if(e == list[0]):
listX.append(e)
elif(e - listX[len(listX)-1] == dif):
listX.append(e)
else:
listY.append(e)
return listX, listY
Check this?
test_list=[0,3,6,9,12,15,18,21,27,33,39,45] #=== List
list_3=[]
list_6=[]
new_list=[]
for j,i in enumerate(test_list): #=== Gives index number for each element in the list
try: #== Check for exceptions, if one occurs, goes to 'except:' statement
op=test_list[j+1] #== Get the elements from index position 1 ahead of the current ome
if op-3==i: #== check if the the difference is 3
list_3.append(i)
elif op-6==i: #== check if the the difference is 6
list_6.append(i)
except:
pass
new_list.append(list_3)
new_list.append(list_6)
print(new_list)

How to remove duplicates from a list using this function?

I'm new to python. Could someone help me understand why the following function doesn't work? It is supposed to return a new list with the duplicates removed but instead prints [4,6].
def remove_duplicates(l):
solution = []
for item in l:
if l.count(item) < 2:
solution.append(item)
else:
l.remove(item)
return solution
print (remove_duplicates([4,5,5,5,4,6]))
I thought it iterates one item at a time in a list. So the first 5 would have a count of 3 and be remove, the second five would have a count of 2 and be removed and the third 5 would have a count of 1 and be appended to the solution list. I can't wrap my head around why the 5s would be completely removed but the 4s would not.
You must not remove items from a list, you are iterating at the moment. Iterating is done by incrementing an index internally.
If you want to keep the last occurence of an item, best, count them at first:
from collections import Counter
def remove_duplicates(l):
solution = []
counts = Counter(l)
for item in l:
if counts[item] == 1:
solution.append(item)
else:
counts[item] -= 1
return solution
Use set data type in python to remove the duplicates.
a = [4,5,5,5,4,6]
solution = list(set(a))
Output:
[4,5,6]

Negative number finder in index and occuring

Write a func/on first_neg that takes a (possibly empty) list of
numbers as input parameter, finds the first occurrence of a
nega/ve number, and returns the index (i.e. the posi/on in the
list) of that number. If the list contains no nega/ve numbers or it
is empty, the program should return None. Use while loop (and
not for loop) and your while loop should stop looping once the
first nega/ve number is found.
This is the question my teacher asked me any ideas this what i did:
def first_neg(list):
count = 0
for number in list:
if number < 0:
count += 1
return count
Dosent seem to work properly i just joined 1st post hope can get some help
x = [1,2,3,-5]
def first_neg(list):
count = 0
for number in list:
count += 1 #moved it outside of the if
if number < 0:
return count
print(first_neg(x)) #prints 4
You want to increment count not when you've found the answer but everytime the forloops loops. Note that this method returns 4 which is the fourth item in the list, not the index, Index of the list starts from 0 so to access it would be 3. Take our list x = [1,2,3,-5], -5 is in the fourth slot of the list, but to access it we have to call x[3] since lists starts at 0 indexing.
If you want to return the index of the list where the first negative number is found try this:
x = [1,2,3,-5]
def first_neg(list):
for count, number in enumerate(list):
if number < 0:
return count
print(first_neg(x)) # prints 3
This is because enumerate creates a "pairing" of the item in the list and it's the current count. Enumerate just counts from 0 everytime it gets an item out of the list.
Also as a side note ( I didn't change it in my answer since I wanted you to understand what's going on ). Don't name your variables keywords like list, tuple, int, str... Just a bad idea and habit, it works as you can see but it can cause issues.
Return the index immediately once you encounter the negative element. Increment the index otherwise:
def first_neg(lst):
count = 0
while count < len(lst):
if lst[count] < 0:
return count
count = count + 1
return None
Note : Better if you use enumerate() rather than using extra count variable. The code you mentioned is not written in pythonic way.
You may try this as well:
def first_neg(lst):
res = [i for i,x in enumerate(lst) if x<0]
return None if res == [] else res[0]
The code above can be improved using generators as suggested by #Chris_Rands.

While loops list index out of range error. Strip off strings with double slases

I was wondering if could help me debug this code. I'm curious as to why I'm getting a list index out of range error. I'm trying to add up all the items in the list and using the number as the index for the list. In the end, I wanted all strings in the list to cut off '//'.
word_list = []
i = 0
while i < len(word_list):
word_list.extend(['He//llo', 'Ho//w are yo//u', 'Be///gone'])
i += 1
word_list[i].strip('//')
print(i)
print(word_list[i])
print(i)
You condition is never True i < len(word_list), i is 0 and the so is the length of your list so you never enter the loop. You cannot index an empty list so print(word_list[i]) with i being 0 gives you an IndexError.
Your next problem is adding more items to your list in the loop so if you did start the loop it would be infinite as the list size would grow faster than i, for example adding a single string to your list initially:
word_list = ["foo"]
i = 0
# i will never be greater than len(word_list) so loops infinitely
while i < len(word_list): # never enter i is not < len(wordlist)
print(i)
word_list.extend(['He//llo', 'Ho//w are yo//u', 'Be///gone'])
i += 1
word_list[i].strip('//')
print(i)
You add 3 elements to your list, you increase i by 1 so that equal an infinite loop. Not sure what your goal is but using a while does not seem to be what you really want.
If you wanted to use a loop to replace the / and you actually have some strings in your list initially:
word_list = ['He//llo', 'Ho//w are yo//u', 'Be///gone']
for i in range(len(word_list)):
word_list[i] = word_list[i].replace("/","")
print(i)
strings are also immutable so you need to reassign the value, you cannot change a string inplace, the above can also simply become a list comp:
word_list = ['He//llo', 'Ho//w are yo//u', 'Be///gone']
word_list[:] = [s.replace("/","") for s in word_list]
I also used str.replace as strip only removes from the start and end of strings.
Here is what's happening in the code:
word_list = [] # you initialize an empty list with no elements
i = 0
while i < len(word_list): # word_list has no elements, so its length is zero
# so this expression is 'while 0 < 0, *which is false*
# so, we skip the loop entirely
print(word_list[i]) # print the word_list[0], the first element of word_list
# word_list has not changed, so still has zero elements at this point
# error! panic! etc
You start with word_list equal to [] which has length 0, and i equal to 0, thus the while loop is never entered (it's false that 0 < 0). When you try to print(word_list[i]) you get an IndexError because there is no ith (0th) element in word_list -- word_list is empty, so index 0 really is out of range.
What you want is presumably:
word_list = ['He//llo', 'Ho//w are yo//u', 'Be///gone']
i = 0
while i < len(word_list):
word_list[i] = word_list[i].replace('//')
print(i, word_list[i])
i += 1
I say "presumably" because maybe you do want the list to grow infinitely and faster than i (joke -- see #Padraic Cunningham's answer, which I think you should accept as the correct one).
use for loop, there no need to keep track of indexing with for loop
import re
for i, w in enumerate(word_list):
word_list[i] = re.sub(r'/+','',w)
print(word_list)
['Hello', 'How are you', 'Begone']

Categories