This program is designed to take a string consisting of numbers (any length) and outputting the contents of the string into a list, one digit at a time. Should a number, x, be less than or equal to the preceding number, y, the number x is to be inserted into a sublist. Until a number, z, is greater than y, everything between x and z will also be added to the sublist. Here is the code
def numbers_in_lists(string):
final = []
temp = []
prev = 0
for i in range(len(string)):
value = int(string[i])
if value<=prev:
temp.append(value)
else:
if temp != []:
final.append(temp)
temp = []
final.append(value)
prev = int(string[i])
print final
return final
To test this function, add the following to the remainder of the code:
string = '543987'
result = [5,[4,3],9,[8,7]]
print repr(string), numbers_in_lists(string) == result
string= '987654321'
result = [9,[8,7,6,5,4,3,2,1]]
print repr(string), numbers_in_lists(string) == result
string = '455532123266'
result = [4, 5, [5, 5, 3, 2, 1, 2, 3, 2], 6, [6]]
print repr(string), numbers_in_lists(string) == result
string = '123456789'
result = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print repr(string), numbers_in_lists(string) == result
After the code creates and returns a sublist, it finds a new maximum value and doesn't add anything else to the list, thus leaving the final list incomplete.
If I test with the string '543987' the prefered result is [5,[4,3],9,[8,7]] whereas my result is [5,[4,3],9]
You need to check temp after the for loop ends, it might still contain something:
def numbers_in_lists(string):
final = []
temp = []
prev = 0
for digit in string:
value = int(digit)
if value<=prev:
temp.append(value)
else:
if temp:
final.append(temp)
temp = []
final.append(value)
prev = int(digit)
if temp:
final.append(temp)
print final
return final
I also slightly re-worked your for loop (no need to use indexed access) and replaced temp != [] with temp (see here).
Related
This question already has answers here:
Recursive method to find the minimum number in a list of numbers
(6 answers)
Closed 2 years ago.
Here is a recursion program
numbers = [1, 2, 3, -3, 5]
numbers0 = [1, 2, 3, 4, 5]
numbers1 = []
def smallest(myList):
if len(myList) == 0:
return -1
else:
return min(myList[0], smallest(myList[1:]))
print(smallest(numbers))
print(smallest(numbers0))
print(smallest(numbers1))
If you just want return the smallest number from the list, you don't need to use recursion
numbers = [1,2,3,-3,5]
numbers0 = [1,2,3,4,5]
numbers1 = []
def smallest(myList):
if len(myList)==0:
return -1
else:
return min(myList)
print(smallest(numbers))
print(smallest(numbers0))
print(smallest(numbers1))
Output:
-3
1
-1
Hey this question was pretty easy:
#--Lists--
numbers = [1,2,3,-3,5]
numbers0 = [1,2,3,4,5]
numbers1 = []
#--Store all list in a list--
myList = [numbers, numbers0, numbers1]
#--List to store the minimum values--
a = []
#--For loop on each list--
for i in myList:
if len(i)==0: #--If it is empty print -1
print(-1)
else: #--If it is not empty, find the minimum--
b = min(i)
a.append(b) #--And then append in a--
print(a) #--Show the values of a--
This should do it and is pretty self explanatory
You can try and do something like this.
numbers = [1,2,3,-3,5]
numbers0 = [1,2,3,4,5]
numbers1 = []
#make a list of all the lists but in sorted order
n = [sorted(numbers),sorted(numbers0),sorted(numbers1)]
#then take the first element of each list. If list is empty, use -1
x = [-1 if not i else i[0] for i in n]
#x will now contain the smallest values from each list
print (x)
Output
[-3, 1, -1]
Another way to do this would be:
#create a list with all the lists
n = [numbers, numbers0, numbers1]
#run thru them and identify the minimum value of each list
#if list is empty, then -1
x = [-1 if not i else min(i) for i in n]
#print the final result
print(x)
Output:
[-3, 1, -1]
The temp in base case is the answer i need.It should be to be appended to the final.But I am ending up with list of empty lists.Any suggestion?
def recur(st,end,a,temp,k,final):
if sum(temp) == k:
final.append(temp)
print(temp)
return
if sum(temp)>k:
return
if st==end-1:
return
st+=1
temp.append(a[st])
recur(st,end,a,temp,k,final)
temp.pop()
recur(st,end,a,temp,k,final)
for _ in range(int(input())):
a = list(map(int,input().split()))
k = int(input())
a.sort()
final = []
temp = []
recur(-1,len(a),a,temp,k,final)
print(final)
I am ending up with list of empty lists.
That is likely due to this statement:
final.append(temp)
You're appending the list temp to final but temp will continue to change after this happens and final will eventually contain one or more pointers to the last value of temp, not it's value when you appended it. To get that, you need to append a copy of temp that won't change:
final.append(list(temp)) # make a copy and stash it away
Generally, I agree with #patmcb regarding our inability to guess what this code is trying to do. However, structurally, I'd expect a properly designed recursive function to look more like:
def recur(start, end, array, temp, target):
total = sum(temp)
if total == target:
return [list(temp)] # a list containing a copy of temp
if total > target or start == end - 1:
return []
start += 1
temp.append(array[start])
result = recur(start, end, array, temp, target)
temp.pop()
return result + recur(start, end, array, temp, target)
for _ in range(int(input())):
a = sorted(map(int, input().split()))
k = int(input())
print(recur(-1, len(a), a, [], k))
OUTPUT
> python3 test.py
1
5 10 13 2 4 6
21
[[2, 4, 5, 10], [2, 6, 13], [5, 6, 10]]
>
I need to have a list going where I have one list with a load of values between 1 and 8 randomly generated and another list with a load of values between 1 and 8 randomly also. I have managed to do this on my code below:
from random import *
listA = []
listB = []
inp = int(input('Number of values generated'))
for x in range(0,inp):
num = randint(0,8)
listA.append(num)
if num == 0:
numB = randint(1,8)
else:
numB = randint(0,8)
listB.append(numB)
print(listA)
print(listB)
The value in the first list can't be 0 and the value in the second list can't be zero too on the same trial. I have this already in my code. However this is the problem I have.
[4, 5, 2, 5, 1]
[1, 2, 3, 2, 4]
In listA, the 5 is produced twice and the 2 below it on the second list is produced twice also. I can't figure out a solution to get these out from my lists, when they create a pair like this.
You can use a helper function as below to generate a unique number that is not in the list and append that to the list.
This should work for you:
def generateUnique(list, start, end): # Helper Function to generate and return unique number not in list
num = randint(start, end)
while num in list: # loop will keep generating a value, until it is unique in the given list
num = randint(start, end)
return num
from random import *
listA = []
listB = []
inp = int(input('Number of values generated'))
for x in range(0,inp):
num = generateUnique(listA, 0, 8)
listA.append(num)
if num == 0:
numB = generateUnique(listB, 1, 8)
else:
numB = generateUnique(listB, 0, 8)
listB.append(numB)
print(listA)
print(listB)
Hope this helps!
I solved the below problem using nested while loops. Is there a way to solve the problem in a simple, Pythonic way?
Question:
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.
They are comparing the subsequent against the previous digit.
For example:
string = '543987'
result = [5,[4,3],9,[8,7]]
string= '987654321'
result = [9,[8,7,6,5,4,3,2,1]]
string = '455532123266'
result = [4, 5, [5, 5, 3, 2, 1, 2, 3, 2], 6, [6]]
My code:
def numbers_in_lists(string):
array = []
for i in string:
array.append(int(i))
temp_list = []
final_list = [array[0]]
i = 0
while i+1 < len(array):
if array[i] >= array[i+1]:
j = 0
while j+1 < len(array[i:]) and array[i] >= array[i:][j+1]:
temp_list.append(array[i:][j+1])
j += 1
final_list.append(temp_list)
i += len(temp_list)
temp_list = []
else:
final_list.append(array[i+1])
i += 1
#print final_list
return final_list
string = '543987'
print numbers_in_lists(string)
[5, [4, 3], 9, [8, 7]]
You can certainly simplify the approach; I would do it as follows:
def numbers_in_lists(string):
"""Describe what it does here!"""
output = []
sublist = []
for num in map(int, string):
if not output or num > output[-1]:
if sublist:
output.append(sublist)
sublist = []
output.append(num)
else:
sublist.append(num)
if sublist:
output.append(sublist)
return output
In use:
>>> numbers_in_lists('543987')
[5, [4, 3], 9, [8, 7]]
>>> numbers_in_lists('987654321')
[9, [8, 7, 6, 5, 4, 3, 2, 1]]
>>> numbers_in_lists('455532123266')
[4, 5, [5, 5, 3, 2, 1, 2, 3, 2], 6, [6]]
This is the solution, you should consider.
num = '455532123266'
final_list = [];
prev = 0
sublist = []
for n in num:
n = int(n)
if (n > prev):
if (sublist != []):
final_list.append(sublist)
sublist = []
final_list.append(n)
else:
sublist.append(n)
prev = n
if sublist != []:
final_list.append(sublist)
print final_list
[4, 5, [5, 5, 3, 2, 1], 2, 3, [2], 6, [6]]
well... Adding my 2 cents :-)
def custom_func(input_string):
if not input_string:
return []
value = input_string[0]
output_list = [int(value)]
for char in input_string[1:]:
if char > value:
# Encountered a value higher than the past maximum
output_list.append(int(char))
else:
if value == str(output_list[-1]):
# First value that is lesser than the past maximum
output_list.append([int(char)])
else:
# nth value which is lesser than the past maximum
output_list[-1].append(int(char))
value = char # updating the past maximum
return output_list
I would consider doing it in more functional way.
def solve(input):
pairs = zip(input, input[1:])
sublist = [False] + map(lambda x: x[0] > x[1], pairs)
result = []
for (val, to_sublist) in zip(input, sublist):
if not to_sublist:
result.append(val)
else:
if isinstance(result[-1], list):
result[-1].append(val)
else:
result.append([val])
return result
This is allows for separation of checking to_sublist predicate and actual building of resulting data structure. To my understanding first number never goes to sublist so it always starts with False.
The problem is not very well-defined, in that the example input does not exactly clarify 2 issues:
What should happen with '567' - should there be empty list after each number
The example cannot tell if you are comparing the subsequent against the previous digit or the first digit of the decreasing subsequence!
Thus here is my take, it is not necessarily the most pythonic, but I couldn't come up with more pythonic solution.
def numbers_in_lists(string):
current_min = -1 # larger than any digit
rv = []
current_list = []
def push_sublist():
if current_list:
largest = current_list.pop(0)
rv.extend([largest, current_list])
for digit in map(int, string):
if digit > current_min:
push_sublist()
current_list = []
current_min = digit
current_list.append(digit)
push_sublist() # if remaining
return rv
As I suspected, the question was not at all clear. Considering how the example code worked, I devised a new algorithm
def numbers_in_lists(string):
current_min = -1 # larger than any digit
rv = []
current_list = []
def push_sublist():
if current_list:
largest = current_list.pop(0)
rv.append(largest)
if current_list:
rv.append(current_list)
for digit in map(int, string):
if digit > current_min:
push_sublist()
current_list = []
current_min = digit
current_list.append(digit)
push_sublist() # if remaining
return rv
The simplest solution I could think of that follows the actual problem statement is:
def numbers_in_lists(string):
output = []
sublist = []
for number in [int(c) for c in string]: # Every number in the string should be inserted into the list.
if output and number <= output[-1]:
"""
- 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.
"""
sublist.append(number)
else:
"""
- Then add this number z to the normal list and continue.
"""
if sublist:
output.append(sublist)
sublist = []
output.append(number)
if sublist:
output.append(sublist)
return output
One other way of doing it... Might be confusing though
_val = int(string[0])
my_lis = [_val]
temp_li = []
for i in string[1:]:
_cval = int(i)
if _cval > _val:
if temp_li:
my_lis.append(temp_li[:])
temp_li = []
my_lis.append(_cval)
_val = _cval
else:
temp_li.append(_cval)
_val = temp_li[0]
if temp_li: my_lis.append(temp_li[:])# last value
print string
print my_lis
Mine is the lazy one:
def num_and_sublist_generator(iterable):
start = -1
sublist = []
for n in iterable:
if n > start:
if sublist:
yield sublist
sublist = []
start = n
yield n
else:
sublist.append(n)
if sublist:
yield sublist
def numbers_in_lists(string):
return list(num_and_sublist_generator(map(int, string)))
I am having trouble getting the results to produce the integer in the list, not which index it falls under.
#this function takes, as input, a list of numbers and an option, which is either 0 or 1.
#if the option is 0, it returns a list of all the numbers greater than 5 in the list
#if the option is 1, it returns a list of all the odd numbers in the list
def splitList(myList, option):
#empty list for both possible options
oddList = []
greaterList = []
#if option is 0, use this for loop
if int(option) == 0:
#create for loop the length of myList
for i in range(0, len(myList)):
#check if index is greater than 5
if ((myList[i])>5):
#if the number is greater than 5, add to greaterList
greaterList.append(i)
#return results
return greaterList
#if option is 1, use this for loop
if int(option) == 1:
#create for loop the length of myList
for i in range(0, len(myList)):
#check if index is odd by checking if it is divisible by 2
if ((myList[i])%2!=0):
#if index is not divisible by 2, add the oddList
oddList.append(i)
#return results
return oddList
the results I receive are as follows:
>>>splitList([1,2,6,4,5,8,43,5,7,2], 1)
[0, 4, 6, 7, 8]
I am trying to get the results to be [1, 5, 43, 5, 7]
You're iterating over the range of the index. Iterate over the list instead.
for i in myList:
#check if index is greater than 5
if i >5:
#if the number is greater than 5, add to greaterList
greaterList.append(i)
So, your code gets rewritten as (with some minor changes)
def splitList(myList, option):
final_list = []
if int(option) == 0:
for i in myList:
if i > 5:
final_list.append(i)
elif int(option) == 1:
for i in myList:
if i%2 != 0:
final_list.append(i)
return final_list
You could reduce it by doing
def splitList(myList, option):
if int(option) == 0:
return [elem for elem in myList if elem > 5]
elif int(option) == 1:
return [elem for elem in myList if elem % 2 != 0]
Output -
>>> splitList([1,2,6,4,5,8,43,5,7,2], 1)
[1, 5, 43, 5, 7]
List comprehensions greatly simplify your code.
def split_list(xs, option):
if option:
return [x for x in xs if x % 2]
else:
return [x for x in xs if x > 5]
if ((myList[i])>5):
#if the number is greater than 5, add to greaterList
greaterList.append(i)
Instead of adding the index i, add the value (myList[i]):
if ((myList[i])>5):
#if the number is greater than 5, add to greaterList
greaterList.append(myList[i])
Same thing for the oddList case.
Note: #Sukrit Kalra's solution is preferable, but I'm leaving this up to show that there's multiple ways of solving this.
Take a closer look at your .append() commands... in your compare you're using:
if ((mylList[i])%2!=0)
or
if ((myList[i])>5)
...but when you put it into the list, you're just using
greaterList.append(i)
instead of
greaterList.append(myList[i])
This must be a homework or class somewhere?