Reputation: 143
This is a practice problem, which reads:
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.
Examples:
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]]
string = '123456789'; result = [1, 2, 3, 4, 5, 6, 7, 8, 9]
My code is as follows:
def numbers_in_lists(s):
n=len(s)
p=[]
i=0
while i<=n-1:
p.append(int(s[i]))
i=i+1
r=[p[0]]
if p[1]<=p[0]:
r.append([p[1]])
else:
r.append(p[1])
if n<=2:
return r
j=2
while j<=n-1:
if p[j]<=p[j-1]:
if p[j-1]<=p[j-2]:
r[-1].append(p[j])
else:
r.append(p[j])
else:
if p[j]<=p[j-2]:
r[-1].append(p[j])
else:
r.append(p[j])
j=j+1
return r
When I tried to run print (numbers_in_lists('543987'))
, I got this:
Traceback (most recent call last):
File "Lesson14Quiz3.py", line 33, in <module>
print (numbers_in_lists(string))
File "Lesson14Quiz3.py", line 20, in numbers_in_lists
r[-1].append(p[j])
AttributeError: 'int' object has no attribute 'append'
The problem seems to be with this line: r[-1].append(p[j])
. But I think when the previous conditions are satisfied, r[-1]
should not be an integer, but a list.
Upvotes: 1
Views: 1880
Reputation: 26039
r
is a list. So, you can safely do r.append(p[1])
. But r[len(r)-1]
is an element in the list r
at position len(r)-1
which is an integer, not a list. r[len(r)-1].append(p[j])
is performing append
on int
which is not possible. Hence this error.
For example:
Consider r = [ 1, 2, 3, 4, 5]
>>> r.append(6)
[1, 2, 3, 4, 5, 6]
>>> r[5].append(7) # here r[5] is 6 which is an integer
AttributeError: 'int' object has no attribute 'append'
With your code, the input s ='4655....'
gives you this error. Because you append 4
,then you see 6
which is greater so you add it as next element. Then you see 5
. Your code will add it as an element. Then again a 5
comes. Here is the problem. At this step, p[j]<=p[j-1]
(5<=5) and p[j-1]<=p[j-2]
(5<=6) are true. So, r[-1].append(p[j])
is done where r[-1]
is 5
(append operation on 5 which is actually an integer).
Please do a traverse through your code. There is logical error, which results in appending to an integer
.
Two problems:
Problem 1: In your code, within the while j<=n-1:
loop, you are not creating any sublists in the list r
. When p[j]<=p[j-1]
is true and p[j-1]<=p[j-2]
is false, actually you need to create a sublist with the item p[j]
. You instead added p[j]
as simply an element in the list.
Problem 2: Your code only checks for last three elements in list. This causes a new item to insert as a new element in the list when it should actually be an element in the sublist.
SOLUTION:
def numbers_in_lists(s):
n=len(s)
p=[]
i=0
while i<=n-1:
p.append(int(s[i]))
i=i+1
r=[p[0]]
if p[1]<=p[0]:
r.append([p[1]])
k = p[1]
else:
r.append(p[1])
k = -1
if n<=2:
return r
j=2
while j<=n-1:
if p[j]<=p[j-1]:
if p[j-1]<=p[j-2] or p[j]<=k:
r[-1].append(p[j])
else:
r.append([p[j]])
k = p[j]
else:
if p[j]<=p[j-2] or p[j]<=k:
r[-1].append(p[j])
else:
r.append(p[j])
j=j+1
return r
Outputs:
'543987' -> [5, [4, 3], 9, [8, 7]]
'987654321' -> [9, [8, 7, 6, 5, 4, 3, 2, 1]]
'455532123266' -> [4, 5, [5, 5, 3, 2, 1, 2, 3, 2], 6, [6]]
'123456789' -> [1, 2, 3, 4, 5, 6, 7, 8, 9]
Upvotes: 4
Reputation: 4248
This line of code:
r[len(r)-1].append(p[j])
breaks down to this:
r: your overall list
len(r): an integer value based on calculation of the length of r
-1: also an integer value
Let's pretend len(r)
is 5.
Thus 5 - 1 is equal to 4.
r[4]
uses Python indexing to identify a specific element in the list r
. Specifically, the element at position 4, starting by counting at index 0.
If the element at position 4 is a number like an integer (rather than a sublist), then Python cannot append anything to the number, cause numbers do not have an .append()
method.
Presuming we have a list that looks like:
r = [7, 13, 42]
And we want to append a 99.
>>> r.append(99)
[7, 13, 42, 99]
But if we index to one of the integers within r
, as opposed to a sublist within r
, we get the error.
>>> r[1].append(99) # r[1] is the value 13.
AttributeError: 'int' object has no attribute 'append'
Lastly, if the item we are indexing to is a sublist, then append()
will work just fine.
# presume r now equals: [7, 13, 42, 99, [1]]
# and we want to append a 1337
>>> r[-1].append(1337) # r[-1] is the last value and is a sublist
[7, 13, 42, 99, [1, 1337]]
This may help solve your problem and may make it easier to troubleshoot the code.
def numbers_in_lists(s):
# use a list comprehension to simplify the process of making a list of
# integers
p = [int(x) for x in s]
# set two sentinel values to help control the code logic/decisions
flag = False
previous_high = 0
# create an empty list
r = []
# iterate over all the digits...
for num in p:
# the code logic is broken into three tests
if num <= previous_high and not flag:
# if flag is False create a sublist
r.append([num])
flag = True
elif num < previous_high and flag:
# if flag is True append to a sublist we previously created
r[-1].append(num)
elif num > previous_high:
# Otherwise, append to the main list again
r.append(num)
previous_high = num
flag = False
return r
>>> numbers_in_list('543987')
[5, [4, 3], 9, [8, 7]]
>>> numbers_in_list('987654321')
[9, [8, 7, 6, 5, 4, 3, 2, 1]]
>>> numbers_in_list('455532123266')
[4, 5, [5, 3, 2, 1, 2, 3, 2], 6, [6]]
>>> numbers_in_list('123456789')
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Upvotes: 4