Python, index out of range, list - python

I need to change the number with the highest index and the number with the lowest index between each other in the entered line, but an error pops out
Error:
list2[0], list2[len1] = list2[len1], list2[0]
IndexError: list index out of range
Code:
list1 = input("Введите список: ")
list2 = list1.split()
len1 = int(len(list2))
list2[0], list2[len1] = list2[len1], list2[0]
print(list2)
How can this be fixed?

Use index [-1] instead of len(list2)-1 to get the last element:
list1 = input("Введите список: ").split()
list1[0], list1[-1] = list1[-1], list1[0]
print(list1)

List are indexing from 0. If your list contains 4 elements, the length is 4 but the last index is 3 (4 - 1).
list1 = input("Введите список: ")
list2 = list1.split()
len1 = int(len(list2)) - 1 # <- HERE
list2[0], list2[len1] = list2[len1], list2[0]
print(list2)

The indexing is always 0 - length-1.
So if you take the list value at length, it will be out of the aforementioned index range.
Another thing I would like to point out is that your variable names are really very confusing. It's a small code, however for bigger projects, when you'll have to debug this, it will be a serious pain for you.
However, this should work
ip = input("Введите список: ")
list1 = ip.split(" ")
len1 = int(len(list1))
list1[0], list1[len1-1] = list1[len1-1], list1[0]
print(list1)

As the Error states, the index for the "list2[len1]" is out of range.
Since len() method in python returns the actual length of the list, whereas the indexing of list starts with 0th position
for the above code, you can try doing this:
list2[0], list2[len1-1] = list2[len1-1], list2[0]

Related

Finding the highest sum of a string in a list

In this task, we creating a function called highsum. It looks at a list of strings and sums up all the numerical characters. We then return the location of the element of the list with the highest value.
For example given list highestSum([“jx72i9r”, “9ch37#r2”, “8rgku3op8”]).
We then must find [17, 21,19] which is all the numerical values added up. Because 21 is the highest value we need the function to return 1 because that is the location of 9ch37#r2 in the list.
This is what I have so far:-
def highestSum(stringList):
number= 0
for xinlist in stringList:
print(xinlist)
for yoflist in xinlist:
print (yoflist)
if yoflist in "1234567890":
number+=int(yoflist)
print(number)
The first for loop cycles through each element while the second for loop cycles through each character in the elements. My accumulator variable work but the problem is I don't know how to let it know when it moves on to a new element.
Another example highestSum([“90gw1xy3”, “12432”, “hfkvbd2”, “*&hdj!4”])
this would return 0 as it as the highest sum of digit characters.
Homemade version
Basically, we gather turn each element in the given list to there digits sum. So like [18,21,19]. Then pair this with original list using zip(). Then use .index() in order to get the corresponding index.
hilarious one-liner
def highestSum(stringList):
return stringList.index({k:v for k,v in zip([sum(list(map(int,[character for character in stringEx if character.isdigit()]))) for stringEx in stringList],stringList)}[max(summed)])
List comprehension & dict comprehension
def highestSum(stringList):
summed = [sum(list(map(int,[character for character in stringEx if character.isdigit()]))) for stringEx in stringList]
highest = max(summed)
pair = {k:v for k,v in zip(summed,stringList)}
return stringList.index(pair[highest])
print(highestSum(["jx72i9r", "9ch37#r2", "8rgku3op8"]))
Easier to understand for the human eye.
def highestSum(stringList):
summed = []
for stringEx in stringList:
gathered = []
for character in stringEx:
if character.isdigit():
gathered.append(character)
gathered = sum(list(map(int,gathered)))
summed.append(gathered)
highest = max(summed)
pair = {}
for k,v in zip(summed,stringList):
pair[k] = v
return stringList.index(pair[highest])
print(highestSum(["jx72i9r", "9ch37#r2", "8rgku3op8"]))
output
1
I have modified your code. Look at this solution. You need a condition to for the highest number in the list and a variable to keep track of its index. See solution below:
def highestSum(stringList):
index = 0
highestValue = 0
for xinlist in stringList:
number= 0
for yoflist in xinlist:
if yoflist in "1234567890":
number+=int(yoflist)
if number > highestValue:
index = stringList.index(xinlist)
highestValue = number
print(index)
stringList = ['jx72i9r', '9ch37#r2', '8rgku3op8']
highestSum(stringList)
def highestSum(stringList):
res = list()
for xinlist in stringList:
number = 0
for yoflist in xinlist:
if yoflist in "1234567890":
number += int(yoflist)
res.append(number)
# find the max position form the accumulator
maxNumPos = 0
for i in range(len(res)):
if res[i] > res[maxNumPos]:
maxNumPos = i
print(maxNumPos)
highestSum(['90gw1xy3', '12432', 'hfkvbd2', '*&hdj!4'])
I'll use list comprehension, maybe it's difficult to read.
code:
x = ["jx72i9r", "9ch37#r2", "8rgku3op8"]
x_to_int = [sum([int(char) for char in s if char.isdigit()]) for s in x]
print(x_to_int.index(max(x_to_int)))
result:
1

How to add the digits in a number and place the result in a list

(sorry for bad title I had trouble sumerizing)So I'm working on a project where a have to take a list of completely random numbers, find the sum of digits in each number, and place that sum in a list. Here is what I have so far:
import random
import math
list1 = [random.randint(1,1000000000000) for i in range(0,10)]
list2 = []
list3 = []
def open_command():
for y in range(0,10):
a = list1[y]
z = len(str(a))
for x in range(0, z):
f = len(str(a))
b = a*0.1
c, w=(math.modf(b))
d = int(c*10)
list2.append(d)
a = (a - d)/10
if f == 0:
total = sum(list2)
list3.append(total)
list2.clear()
open_command()
print(list3)
When I run this code the list3 just displays an empty list however there is no error. I don't understand, Is the .append not working? Can somebody explain what is going on?
Using map, One liner
list_num = [123,456]
print([sum(list(map(int, list(str(num))))) for num in list_num])
Output:
[6, 15]
That comes because the following code never got executed. List 3 is never appended and the list 2 never gots clear.
if f == 0:
total = sum(list2)
list3.append(total)
list2.clear()
You never change a, so the length of it (f) never becomes 0. Therefore, you never append anything.
But you're overcomplicating things:
list3 = [sum(int(char) for char in str(num)) for num in list1]
Or, if you want to keep your basic concept:
def open_command():
for number in list1:
for char in str(number):
list2.append(int(char))
list3.append(sum(list2))
list2.clear()
return list3

How can I take a list and append each element to a new list depending on its position?

So my first list created via a for loop looks like the following
["1variable1", "1variable2", "1variable3", "1variable4", "1variable5"].
I then want it to be appened to new list depending on their position.
so List1 will be [1variable1]
List2 will be [1variable2]
etc
Then the next step of the loop will create another
["2variable1", "2variable2", "2variable3", "2variable4", "2variable5"]
I then want to append that to the previous list to make;
List1 will be [1variable1, 1variable2]
List2 will be [1variable2, 2variable2]
etc.
At the moment I have it so that it simply used square brackets to pull out each part of the list but I don't know how to get this in a loop, maybe next time I run it there will be more than 4 entries and I will miss the 5th.
lst1 = [item[0] for item in Genres]
lst2 = [i[1] if len(i) > 1 else '' for i in Genres]
lst3 = [i[2] if len(i) > 2 else '' for i in Genres]
lst4 = [i[3] if len(i) > 3 else '' for i in Genres]
lst5 = [i[4] if len(i) > 4 else '' for i in Genres]
If the next list doesn't have as many as a previous list then it should fill in a blank space as they all need to be in the same position
The lists are created as follows;
my_list = my_list[1:]
length = len(my_list)
my_list = my_list[0:3]
for film in my_list:
filmIndex = my_list.index(film) + 1
query = film + " imdb"
for j in search(query, tld="co.in", num=10, stop=1, pause=2):
page = requests.get(j)
response = page.status_code
if response == 200:
soup = BeautifulSoup(page.content, "lxml")
genreData = soup.find_all("div",{"class":"subtext"})
Then
for h in genreData:
a = h.find_all('a')
aLength = len(a)
a1 = a[0]
for b in range(0,aLength - 1):
r = a[b].string
genres.append(r)
I then want to add each genre into a seperate column, genre1, genre2 etc. up to how ever many max is. Obviously some of these mull be NULL if the max is 4 and one film only has 1
Then for each film will create a list of all the genres for that film and I want to put them into separate columns
One possible method is to create a list of lists.
Creating a list of lists lets you iterate through the list to insert and place each variable into the list at the variable's index. Of course, if you've got a big list or are doing your first pass, you'll hit an index you haven't encountered yet, so you'll need to init an empty list at that index.
list1 = ["1variable1", "1variable2", "1variable3", "1variable4", "1variable5"]
list2 = ["2variable1", "2variable2", "2variable3", "2variable4", "2variable5"]
biglist = []
#insert list1
#this for loop can be repeated for every list you want to enter - maybe
#put those into a list of lists, too?
for i in range(0, len(list1)):
#check to see if there's a list in this entry
if 0 <= i < len(biglist):
#there's already a list here, add this to it
biglist[i].append(list1[i])
else:
#there's no list here yet, create one and add its first variable
biglist.append([])
biglist[i].append(list1[i])
#repeat for the second list, and so on - you can nest these
for i in range(0, len(list2)):
if 0 <= i < len(biglist):
biglist[i].append(list2[i])
else:
biglist.append([])
biglist[i].append(list2[i])
for l in biglist:
print(l)
Demo

indexError: list indexing error and wrongful tracking of counters

The goal of the program is to 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.
#testcases
string = '543987'
numbers_in_lists(string)
result = [5,[4,3],9,[8,7]]
def numbers_in_lists(string):
# Convert the sequence of strings into an array of numbers
i = 0
conv_str_e = []
while i < len(string):
conv_str_e.append(int(string[i]))
i += 1
#official code starts here
normal_list = []
list_of_small_nums = [[]]
# This will help me keep track of elements of the normal_list.
previous_e_pos = -1
e_pos = 0
# this one will be used to decide if the element should go into the
#normal_list or list_of_small_nums
check_point = 0
for e in conv_str_e:
#The first element and every elements bigger the element with
#check_point as it's index
#will be put into the normal_list as long as the list inside
#list_of_small_nums is empty
if e_pos == 0 or e > conv_str_e[check_point]:
#If the list inside list_of_small_nums is not empty
if list_of_small_nums[0] != []:
#concatenate the normal_list and list_of_small_nums
normal_list = normal_list + list_of_small_nums[0]
#Clear the list inside list_of_small_nums
list_of_small_nums[0] = []
#Add the element in the normal_list
normal_list.append(e)
# Update my trackers
e_pos += 1
previous_e_pos += 1
# (not sure this might be the error)
check_point = e_pos
#The curent element is not bigger then the element with the
#check_point as index position
#Therefor it goes into the sublist.
list_of_small_nums[0].append(e)
e_pos += 1
previous_e_pos += 1
return list
What you were doing wrong was exactly what you pointed out in your comments. You just kept increasing e_pos and so check_point eventually was greater than the length of the list.
I took the liberty of changing some things to simplify the process. Simple programs make it easier to figure out what is going wrong with them. Make sure you always try to think about the simplest way first to solve your problem! Here, I replaced the need for e_pos and previous_e_pos by using enumerate:
string = '543987'
# Convert the sequence of strings into an array of numbers
conv_str_e = [int(i) for i in string]
#official code starts here
normal_list = []
list_of_small_nums = []
# this one will be used to decide if the element should go into the
#normal_list or list_of_small_nums
check_point = 0
for ind, e in enumerate(conv_str_e):
#The first element and every elements bigger the element with
#check_point as it's index
#will be put into the normal_list as long as the list inside
#list_of_small_nums is empty
if ind == 0 or e > conv_str_e[check_point]:
#If the list inside list_of_small_nums is not empty
if list_of_small_nums != []:
#concatenate the normal_list and list_of_small_nums
normal_list.append(list_of_small_nums)
#Clear the list inside list_of_small_nums
list_of_small_nums = []
#Add the element in the normal_list
normal_list.append(e)
# Update my trackers
check_point = ind
else:
#The curent element is not bigger then the element with the
#check_point as index position
#Therefore it goes into the sublist.
list_of_small_nums.append(e)
# If there is anything left, add it to the list
if list_of_small_nums != []:
normal_list.append(list_of_small_nums)
print(normal_list)
Result:
[5, [4, 3], 9, [8, 7]]
I am sure you can change it appropriately from here to put it back in your function.

How to find the position of first instance of duplicates in two equal length, sorted lists

I have two random lists of same length, in range of 0 to 99.
lista = [12,34,45,56,66,80,89,90]
listb = [13,30,56,59,72,77,80,85]
I need to find the first instance of a duplicate number, and in what list it is from.
In this example, I need to find the number '56' in listb, and get the index i = 2
Thanks.
Update:
After running it a couple of times, I got this error:
if list_a[i] == list_b[j]:
IndexError: list index out of range
like #Asterisk suggested, my two lists are equal length and sorted, both i and j are set to 0 at the beginning.
that bit is part of a genetic crossover code:
def crossover(r1,r2):
i=random.randint(1,len(domain)-1) # Indices not at edges of domain
if set(r1) & set(r2) == set([]): # If lists are different, splice at random
return r1[0:i]+r2[i:]
else: # Lists have duplicates
# Duplicates At Edges
if r1[0] == r2[0]: # If [0] is double, retain r1
return r1[:1]+r2[1:]
if r1[-1] == r2[-1]: # If [-1] is double, retain r2
return r1[:-1]+r2[-1:]
# Duplicates In Middle
else: # Splice at first duplicate point
i1, i2 = 0, 0
index = ()
while i1 < len(r1):
if r1[i1] == r2[i2]:
if i1 < i2:
index = (i1, r1, r2)
else:
index = (i2, r2, r1)
break
elif r1[i1] < r2[i2]:
i1 += 1
else:
i2 += 1
# Return A Splice In Relation To What List It Appeared First
# Eliminates Further Duplicates In Original Lists
return index[2][:index[0]+1]+index[1][index[0]+1:]
The function takes 2 lists and returns one.
domain is a list of 10 tupples: (0,99).
As I said, the error doesn't happen every time, only once in a while.
I appreciate your help.
I'm not a python guy, but this is an algorithm question...
You maintain an index into each list and you look at the elements at those two list positions.
Whichever list has the smallest element at the current position, you move to the next element in that list.
When you find an element that is the same as the other list's current element, that is your smallest duplicate.
If you reach the end of either list, there are no duplicates.
If you're looking for all the duplicates, you can use something like this:
list_a = [12,34,45,56,66,80,89,90]
list_b = [13,30,56,59,72,77,80,85]
set_a = set(list_a)
set_b = set(list_b)
duplicates = set_a.intersection(set_b)
# or just this:
# duplicates = [n for n in list_a if n in list_b]
for duplicate in duplicates:
print list_a.index(duplicate)
To get the smallest index of a duplicate in either list:
a_min = min(map(list_a.index, duplicates))
b_min = min(map(list_b.index, duplicates))
if a_min < b_min:
print 'a', a_min, list_a[a_min]
else:
print 'b', b_min, list_b[b_min]
If not, this should work a bit better:
duplicate = None
for n in set_a:
if n in set_b:
duplicate = n
break
if duplicate is not None:
print list_a.index(duplicate)
lista = [12,34,45,56,66,80,89,90]
listb = [13,30,56,59,72,77,80,85]
i, j = 0, 0
while i < len(lista):
if lista[i] == listb[j]:
if i < j:
print i, lista
else:
print j, listb
break
elif lista[i] < listb[j]:
i += 1
else:
j += 1
>>>
2 [13, 30, 56, 59, 72, 77, 80, 85]
Assumptions: both lists have the same length, and they are sorted
Just scan all the lists at position 0, then 1, then 2, ... Keep track of what you've seen (you can query a set in O(1) time).
def firstDuplicate(*lists):
seen = {}
for i,tup in enumerate(zip(*lists)):
for listNum,value in enumerate(tup):
position = (listNum,i)
if value in seen:
return value, [seen[value], position]
else:
seen[value] = position
Demo:
>>> value,positions = firstDuplicate(lista,listb)
>>> value
56
>>> positions
[(1, 2), (0, 3)]
(Does not generalize to N lists... yet. Would need a minor tweak to use a defaultdict(set), insert all indices as a tuple together, then check for duplicates.)

Categories

Resources