This question already has answers here:
'NoneType' object has no attribute 'append' python
(4 answers)
Closed 3 years ago.
I have a homework problem where we have to count the amount of rectangular blocks used in the construction of a pyramid design. The pyramid design consists of 'x' rows, 'y' columns and 'z' layers. For example if the values x = 2, y = 3, z = 1 were entered, the program would output 6, which would be the number of blocks. Every layer that comes after has one more row (x+1) and one more column(y+1). So if the values x = 2, y = 3, z = 2 were entered, 12 would be returned which is the number of total blocks and so on.
This is what I have so far but I keep getting an error:
def blocks(x,y,z):
if z == 1:
return x * y
else:
result = []
total = x * y #<--- initial calculation
for i in range(z):
total = ((x+1)*(y+1))
result = result.append(total)
print (blocks(2,3,4))
The error message I get is:
result = result.append(total)
AttributeError: 'NoneType' object has no attribute 'append'
list.append() returns None, so your reassignment:
result = result.append(total)
will reassign result to None on each iteration of your loop. Instead, remove the reassignment, since append modifys the existing list in place.
replace result = result.append(total)
with result.append(total)
when you append an object to a list, there is no need to set the result equal to a new list; it does the appending on the list in place.
Related
This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 1 year ago.
I know there are many similar questions like this but I am not sure why my code doesn't work.
Basically, what I am trying to do is to initialize a 2D array to all 0s, get user input (row, column), and set the position to 1.
def printBoard(positions):
for row in positions:
print(row)
def main()
x= int(input())
column = [0] * x
Board= [column] * x
printBoard(Board)
for i in range(x):
row, column = map(int, input().split())
Board[row][column] = 1
printBoard(Board)
main()
But the output is now what I expect.
>>>2
[0, 0]
[0, 0]
>>>1,1
[0, 1]
[0, 1]
As you can see, the whole column is changed. May I ask why?
When you execute
Board= [column] * x
it will result in a list in which all rows (i.e. internal lists) will be the same object (x times the list column), so when you update any element of any of those (same) lists, you will see the result x times, since all the rows (or columns as you call it) are exactly the same, because they are the instances of the same object.
This question already has answers here:
Computing average of non-zero values
(3 answers)
Closed 3 years ago.
How to get mean from list that is partially empty example [0,2,4,0,4,0,0,0,0,10]
So mean should be (2+4+4+10)/4 = 5 , but statistics.mean() divides by the overall amount of numbers in the list (which in this case is 10).
So in my case I need to get mean from the list of numbers which are divisible by 3 (list b)
import random
import statistics
a = []
b = []
c = [0,2,4,0,4,0,0,0,0,10]
for x in range (10):
a.append(random.randint(0,101))
for x in a:
if x%3==0:
b.append(x)
else:
b.append(0)
average = statistics.mean(b)
print('a',a)
print('b',b)
print('Srednia',average)
You can filter out the zeros from the list using a for-loop perhaps
from statistics import mean
c = [0,2,4,0,4,0,0,0,0,10]
#Filter out 0's
non_zero_c = [item for item in c if item]
#Calculate mean from non zero numbers
print(mean(non_zero_c))
The output will be 5
In alternative to creating a list of only non-zero elements you can count them
non_zero_mean = sum(x) / sum(element != 0 for element in x)
here I'm using the "trick" that from a math point of view in Python (like in C and C++) True == 1 and False == 0.
Another alternative is
non_zero_mean = sum(x) / (len(x) - x.count(0))
Very quickly, the easiest way is to use some list comprehension to select the part of the list that interest you.
Example:
"How to get mean from list that is partially empty example [0,2,4,0,4,0,0,0,0,10] "
a = [0,2,4,0,4,0,0,0,0,10]
a_selection = [elt for elt in a if elt != 0]
m = sum(a_selection)/len(a_selection)
Same for divisible by 3:
b_selected = [elt for elt in b if elt%3==0]
This question already has answers here:
Why do these list operations (methods: clear / extend / reverse / append / sort / remove) return None, rather than the resulting list?
(6 answers)
Closed 3 years ago.
I've started going through Udacity course Intro to Computer Science and I've come up against following problem:
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.
I've found this solution, which works without problem:
def numbers_in_lists(theString):
maxNum = int(theString[0])
mainList = [maxNum]
for e in theString[1:]:
num = int(e)
if num > maxNum:
mainList.append(num)
maxNum = num
else:
if (type(mainList[-1]) == list):
mainList[-1].append(num)
else:
mainList.append([num])
return mainList
This is my code.
def numbers_in_lists(s):
p = [int(s[0])]
n = len(s)
i = 1
while i < n:
first = int(s[i-1])
second = int(s[i])
if (second > first): p = p.append(second)
if (second <= first):
if (type(p[-1]) == list): p[-1].append(second)
else: p.append([second])
i = i + 1
return p
It's similar, apart from while loop. I get an error
line 10, in numbers_in_lists
if (type(p[-1]) == list): p[-1].append(second)
TypeError: 'NoneType' object is not subscriptable
I get the solution, but I don't understand why my code isn't working and how to fix the error.
This is the problem:
if (second > first): p = p.append(second)
The append() method modifies the original list; it doesn't return a new list. It returns None.
Just use p.append(second).
x = input()
y = map(int, input().split())
score = list(y)
score2 = score.remove(max(score))
print(max(score2))
When I execute the above code with inputs x = 4 and y = 1 2 3 4, it shows an error message 'NoneType value is not iterable'. The last but previous line 'score2 = score.remove(max(score))' returns a None value. Why does this happen? I intend to create code which fetches the second largest number in the list
Method remove() from list doesn't return anything. It changes list inplace. So your score2 value will be always None.
The corrected program should look like (with few cosmetic corrections, will work for input of 2 values and higher):
score = sorted(map(int, input().split()))[-2]
print(score)
Why don't you just do -
y=[1, 2, 3, 4]
max_num = max(y)
print(max(num for num in y if num!=max_num))
what = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6]
len(what) # size 16
rwhat = what[::-1] # reverse the order of what & work with this
rwhat
checkDig = rwhat[0] # the leftmost [originally rightmost] digit which is the # checkDigit is 6
checkDig # 6
withCheck = [] # to append later when we add all single digits
everySec = rwhat[1:16:2] # we don't want to double the checkDigit. extract value of every second digit.
everySec # [5, 3, 1, 9, 7, 5, 3, 1]
def double(num):
return [j * 2 for j in everySec] # double the value of every second digit
xx = double(everySec)
xx # [10, 6, 2, 18, 14, 10, 6, 2]
def getSingle(y): # we want to sum the digits of numbers (that were doubled) that are greater than 9 and keep these sums along with the numbers that didn't need to be summed.
u = 0
while y:
u += y % 10
y //= 10
return u
When I try
getSingle(xx) to return the latest function and get a list of only single digits, I'm given this error TypeError: unsupported operand type(s) for %: 'list' and 'int'
I've explained what's going on in the comments throughout the code, but if more clarification is needed please feel free to ask. This isn't even the entire program, but I need this last function to work to move forward.
EDIT
Ok, so it works. Now if I wanted to create a function outside of all this code (as in this code will be in the inside of the new function), how would I go about doing so when the function should have only 1 parameter which is a multidimensional array w/ 16 columns. I'm stuck on how/where I'd indicate this specification.
Your problem is caused by the fact that when you call getSingle(xx), you are inputting a list instead of an integer. The % can not be cast to the whole list in the way you intended. Possible solutions include:
Iterate over List
def getSingle(y):
y = eval(repr(y)) #deep copy y in case we want to use it again later
u = [0]*len(y)
for i in range(len(y)):
while y[i]:
u[i] += y[i] % 10
y[i] //= 10
return u
This would apply your digit summing operation to all of the elements of the list and return the sum in u.
Numpy
Alternatively, if you plan on doing operations on the whole list many times, we could use numpy (never import a library to use only once)
import numpy as np
def getSingle(y):
y = np.array(y)
u = np.zeros(y.shape) #create an array of 0s the same size
while np.any(y): #checks to see if any elements in y are more than 0
u += y % 10 #operation applies to all in y
y //= 10 # operation applies to all in y
return u
Map
And as pointed out in the comments, another alternative would be to use map on the existing function.
result = map(xx, getSingle) #fixed code
You would have to call this outside of the function definition in place of the original call
result = getSingle(xx) #original code with error
documentation for map is here
In python 3 map returns an object which can be turned into a list by applying the list function
result = list(map(xx, getSingle))