How to end this infinite loop - python

I have to sort a user inputed list from lowest to highest without . sort, but when I try to replace two values to put them in order I find myself in an infinite loop
list = input('Enter list of numbers separated by a space: ').split()
list = [int(b) for b in list]
def list_sort(list):
while list:
a = list[0] # random number in list
for x in list: # to check every number in the list
if x < a: # find if the new number is less than original
c, d = list.index(x), list.index(a)
list[d], list[c] = list[c], list[d]
print(list_sort(list))

You are setting your while loop to run as long as list is True, which in your code is always going to be true. What you want to do instead is set up a condition inside your while loop to break out of your loop with a break statement.
while True:
if some_break_condition_met:
break
else:
# do logic
Also, list is used in python to create a list, so I strongly suggest not using list as your variable, maybe change it to lst or my_list. Using list could cause problems.

list = input('Enter list of numbers separated by a space: ').split(' ')
list = [int(b) for b in list]
def list_sort(list):
updated = True
while updated:
updated = False
for orig_index in range(0, len(list)):
for check_index in range(orig_index, len(list)):
if list[check_index] < list[orig_index]:
list[orig_index], list[check_index] = list[check_index], list[orig_index]
updated = True
print(list_sort(list))

Related

check if 2 lists aren't the same print empty list

I have tried to write an if/else statement check if the 2 lists I'm working with don't share any values. If they don't, I want to return an empty list. I can't work out how. Whenever I add in the statement if messes up my code to print inside the function and prints it the about of times a list item was entered or says invalid syntax.
The program is supposed to compare 2 lists, only print out the numbers they share in the list, only print single numbers if they repeat. If an empty string is entered, exit the program. If the lists don't share numbers print an empty list e.g Output: []
This is what I have so far. Should I also be using a return statement instead of print?
def mylist(list1,list2):
same_num = []
for i in list1:
if i in list2:
same_num.append(i) #put matching numbers into a list
output = set(same_num) #convert to a set where no 2 thing will be the same
output_list = list(output) #convert back to list for output
print("Output: ", *output_list)
else:
print("Output: ", same_num)
ui1 = input('List 1: ')
if ui1 == "":
print(" ")
else:
ui2 = input('List 2: ')
list1 = list(ui1)
list2 = list(ui2)
mylist(list1, list2)
As you figured out already, you want to use a set for doing that. Sets keep only the unique elements and implement more efficient algorithms to check for intersection. In your case:
def mylist(list1,list2):
res = set(list1).intersection(set(list2))
print("Output: ", *res)
return
The simplest way to do this:
def common(xs, ys):
return list(set(xs).intersection(set(ys)))
xs = [...]
ys = [...]
print(common(xs, ys))
Some remarks:
If you want to exit when the input is empty, you need a loop for when it is not.
As input returns a string, calling list() on it will produce a list with separate characters. You don't want to separate '19 25' into ['1', '9', ' ', '2', '5'], so first split into words, then map those words to numbers.
To get unique values (removing duplicates), use a set. To get values which are common in both lists, use the intersection method on the set.
Here is how it could look:
ui1 = input('List 1: (enter to quit)').split()
while ui1:
ui2 = input('List 2: ').split()
list1 = list(map(int, ui1))
list2 = list(map(int, ui2))
result = list(set(list1).intersection(list2))
print(result)
# Again: ...
ui1 = input('List 1: ').split()

Reading an array from stdin using input() function throws an EOF error

Basically, I wish to sum the elements of the array provided in stdin. Why is it saying that list index is out of range? Is there anything special about the python input() function?
length = int(input())
li = []
for i in range(0, length):
li[i] = int(input())
sum = 0
for item in li:
sum = sum + item
Input
first line : length of array
second line : elements of the array.
EDIT : second line is a single string, not space separated integers.
3
1 2 3
Output:
Traceback (most recent call last):
File "./prog.py", line 6, in <module>
IndexError: list assignment index out of range
your question pretty much got answered, I just wanna show you a couple of tricks to make your program more simple and pythonic.
Instead of the for-loop try:
li = [int(i) for i in input().split(" ")]
And instead of the way you're calculating sum, try:
sum(li)
or even better:
sumOfItems = sum(int(i) for i in input().split(" "))
The thing with python lists is that you cannot assign a particular value to a position when that position originally does not exist, that is, the length of the list is less than the position that you want to change.
What you are trying to do is assign the value to a particular position in the list (called index) but since the list is empty, it's length is 0 and hence the index is out of range( that is it is not available for modifiying. That is why python is raising Index out of range error.
What you can try is:
l=[]
length=int(input())
for i in length:
l.append(int(input())
sum=0
for num in l:
sum=sum+num
You can solve this in a single line without even taking in the length. But you have to enter space separated values in a single line:
s = 0
for item in list(map(int, input ().split())):
s += item
If you want to input one integer per line, then you'll need the length(or a sentinel value):
s = 0
len = int(input())
li = [int(input ()) for _ in range(len)]
for item in li:
s = s + item
The second line of input turned out to be a single string and not space separated integers.
So I had to split the string, then convert the strings to integers to calculate their sum. Some of the methods mentioned above didn't work.
The list comprehension method will work in the space separated case, and is perfectly fine.
length = int(input())
l = input().split() # List of strings of integers.
S = 0
for item in l:
S += int(item) # Converting string to int
print(S)
You can't assign values to locations of a list that doesn't exist
try this:
length = int(input())
li = list(range(length))
for i in range(0, length):
li[i] = int(input())
sum = 0
for item in li:
sum = sum + item
you can also do something like this:
length = int(input())
li = []
for i in range(0, length):
li.append(int(input()))
total = sum(li)
print(total)

Largest substring of non-repeating letters of a string

From the beginning I want to point out, that I am using Python Language. In this question I initially have a string. For example 'abcagfhtgba'. I need to find the length of the largest substring of non-repeating letters. In the case provided above it is 'agfht' (5), because at position [4] the 'a' repeats, so we start the count from the begining.
My idea for this question is to create a dictionary, which stores letters as keys, and numbers of their appearances as values. Whenever any key has corresponding value 2, we append the length of the dictionary to the list named result and completely substitute it with an empty list. For some tests this approach holds, for some not. I will provide the code that I used with brief comments of explanation.
Here I store the input in form of a list
this = list(map(str, input()))
def function(list):
dict = {}
count = 0
result = [1]
Here I start the loop and for every element if it is not in the keys I create a key
with value 1. If the element is in the dictionary I substitute the dict with the empty one. I don't forget to store the first repeating element in a new dictionary and do this. Another important point is at the end to append the count after the loop. Because the tail of the string (if it has the largest non-repeating sequence of letters) should be considered.
for i in range(len(list)):
if list[i] not in dict:
dict[list[i]] = 1
count += 1
elif list[i] in dict:
dict = {}
dict[list[i]] = 1
result.append(count)
count = 1
result.append(count)
print(result)
return max(result)
Here i make my function to choose choose the largest between the string and the inverse of it, to deal with the cases 'adabc', where the largest substring is at the end.
if len(this) != 0:
print(max(function(this), function(this[::-1])))
else:
print('')
I need help of people to tell me where in the approach to the problem I am wrong and edit my code.
Hopefully you might find this a little easier. The idea is to keep track of the seen substrings up to a given point in a set for a faster lookup, and if the current value is contained, build the set anew and append the substring seen up to that point. As you mention you have to check whether the last values have been added or not, hence the final if:
s = 'abcagfhtgba'
seen = set()
out = []
current_out = []
for i in s:
if i not in seen:
current_out += i
seen.update(i)
else:
seen = set(i)
out.append(''.join(current_out))
current_out = [i]
if current_out:
out.append(''.join(current_out))
max(out, key=len)
# 'agfht'
So some key differences:
Iterate over the string itself, not a range
Use sets rather than counts and dictionaries
Remember the last duplicate you have seen, maintain a map of letter to index. If you have already seen then this is duplicate, so we need to reset the index. But index can be this new one or just after the last duplicate character is seen.
s = 'abcagfhtgba'
seen = dict()
longest = ""
start = 0
last_duplicate = 0
for i, c in enumerate(s):
if seen.has_key(c):
if len(longest) < (i - start + 1):
longest = s[start:i]
new_start = seen.get(c) + 1
if last_duplicate > new_start:
start = i
else:
start = new_start
last_duplicate = i
seen[c] = I
if len(longest) < (len(s) - start + 1):
longest = s[start:]
print longest

How to ask the user to enter numbers and then sum the numbers which are divisible by 3?

I want to make a Python script which has the user enter 7 numbers and then check which numbers can be divided by 3, then sum those numbers, and show it to the user as "sum=xx".
I tried:
input_string = input("Enter a list element separated by space ")
list = input_string.split()
Here is using list comprehension,
input_string = input("Enter a list element separated by space ")
numbers = [int(num) for num in input_string.split(',') if int(num) % 3 == 0]
print('Sum = {}'.format(sum(numbers)))
This is based on your question above.
But, you also said that you would want user to input 7 numbers and find sum for numbers which are divisible by 3.
Here is other simple example, where we ask user to input 7 numbers, one number at a time and print sum at the end.
all_numbers = []
for i in range(7):
num = int(input(f'Enter number {i + 1}:\n1'))
all_numbers.append(num)
sum_of_numbers = sum([num for num in all_numbers if num % 3 == 0])
print(f'Sum = {sum_of_numbers}')
You can get a list of integers from the input using the int function which gives you an integer object from a string, since the split function only gives you a list of separated strings.
input_string = input("Enter a list element separated by space ")
my_list = input_string.split()
numbers = []
for n in my_list:
numbers.append(int(n))
However, this will throw a ValueError if n is not a valid number (e.g. "a"), which you can catch with a try-exceptstatement.
Notice how I changed the name of your variable to my_list because the name list already has a meaning in Python and it's a good practice to not assign it to a variable.
If you want to do it in a single step, you can use the useful map function to apply the int function to all of the elements in list. You can check the documentation for this function, as well as any other on the python documentation, or using the help built-in function. (e.g. help(map))
numbers = map(int, my_list)
You can then check if there are 7 numbers in the list by using the len function, and if there aren't 7 you can prompt the user to input the numbers again if that is what you want to do.
>>> my_list = [1, 2, 3]
>>> len(my_list) == 3
True
If you want to keep prompting the user until there are seven numbers on your list, you can put the prompt inside a while block, like shown:
numbers = [] # We create an empty list
while len(numbers) != 7:
input_string = input("Enter a list element separated by space ")
my_list = input_string.split()
numbers = list(map(int, my_list)) # Get the numbers
After getting the numbers, you can see which ones are divisible by 3 by using the modulo operator, which gives you the rest of dividing a number by another (3 in your case). Some examples:
>>> 7%3 # 7 = 3*2 + 1
1
>>> 19%5 # 14 = 5*3 + 4
4
>>> 8%4 # 8 = 4*2 + 0
0
Since you want to check which numbers of your list are divisible by 3 you can check whether this module is 0 or not inside of a loop through the list.
If the numbers are divisible by 3, you can add them to a counting variable, you could initialize to 0 before the loop. That way, after the loop you'd get the sum you want in this variable.
Another, more elegant way of doing so is using a list comprehension instead of a loop, which would only retain the numbers divisible by 3, and then sum its elements using the sum function.
new_list = [x for x in numbers if x%3 == 0]
sum = sum(new_list)

how can i compare string within a list to an integer number?

my task today is to create a function which takes a list of string and an integer number. If the string within the list is larger then the integer value it is then discarded and deleted from the list. This is what i have so far:
def main(L,n):
i=0
while i<(len(L)):
if L[i]>n:
L.pop(i)
else:
i=i+1
return L
#MAIN PROGRAM
L = ["bob", "dave", "buddy", "tujour"]
n = int (input("enter an integer value)
main(L,n)
So really what im trying to do here is to let the user enter a number to then be compared to the list of string values. For example, if the user enters in the number 3 then dave, buddy, and tujour will then be deleted from the list leaving only bob to be printed at the end.
Thanks a million!
Looks like you are doing to much here. Just return a list comprehension that makes use of the appropriate conditional.
def main(L,n):
return([x for x in L if len(x) <= n])
Just use the built-in filter method, where n is the cut off length:
newList = filter(lambda i:len(i) <= n, oldList)
You should not remove elements from a list you are iterating over, you need to copy or use reversed:
L = ["bob", "dave", "buddy", "tujour"]
n = int(input("enter an integer value"))
for name in reversed(L):
# compare length of name vs n
if len(name) > n:
# remove name if length is > n
L.remove(ele)
print(L)
Making a copy using [:] syntax:
for name in l[:]:
# compare length of name vs n
if len(name) > n:
# remove name if length is > n
L.remove(ele)
print(L)
This is a simple solution where you can print L after calling the main function. Hope this helps.
def main(L,n):
l=len(L)
x=0
while x<l:
#if length is greater than n, remove the element and decrease the list size by 1
if len(L[x])>n:
L.remove(L[x])
l=l-1
#else move to the next element in the list
else:
x=x+1

Categories

Resources