python 'int' object has no attribute 'sort' - python

Hey I am new to Python and I have this exercise I want to complete but I get the following error: 'int' object has no attribute 'sort'.
I must use for-loop to take from a list of numbers and make them all square, then print them all out one by one as sorted.
Did I use the sort command incorrectly? Or it doesen't even work with numbers? And do I have to use the .append() command to make them all print out one by one?
So this is my wannabe code so far:
start_list = [5, 3, 1, 2, 4]
square_list = []
for square_list in start_list:
square_list ** 2
print square_list.sort()

There are three issues:
You're assigning from the start_list over your square_list in the for loop.
You're not appending your result into the list (this would fail anyway, because of the above).
The end result is that your square_list is not a list and so cannot be sorted.
Compare the following code:
start_list = [5, 3, 1, 2, 4]
square_list = []
for item in start_list:
square_list.append(item ** 2)
Here we iterate over the list taking an item for each loop. We then square it (using ** 2) and then append it to square_list.
There is also an issue in the print statement: print square_list.sort()
Here you are using .sort() on the list and then trying to print the returned value. But .sort() sorts the list in place and then returns None. So this line will always print None. To print the sorted list you can either use the sorted() function which returns the sorted list, ready to be passed to print:
print sorted(square_list)
Or you can sort the list before printing:
square_list.sort()
print square_list

The most pythonic solution is
start_list = [5, 3, 1, 2, 4]
square_list = [ i ** 2 for i in start_list ]
print(sorted(square_list))
or oneliner:
print(sorted(i ** 2 for i in [5, 3, 1, 2, 4]))
Let's dissect your code:
# here you create an empty list and assign it to
# square list
square_list = []
# yet here you will assign each item of start_list
# to the name square list one by one
for square_list in start_list:
# then you square that number, but it is not stored anywhere
square_list ** 2
# at this point, square_list contains the last element
# of start_list, that is the integer number 4. It does
# not, understandably, have the `.sort` method.
print square_list.sort()
The straightforward fix would be to do:
start_list = [ 5, 3, 1, 2, 4 ]
square_list = []
for element in start_list:
square_list.append(element ** 2)
square_list.sort() # note that printing this would say "None"
print square_list

You must understand for loops.
for square_list in start_list:
square_list ** 2
square_list in this example doesn't refer to the empty list you made. It is used as an ambiguous variable to extract values from a list. As such, this is just the each value in the list during each iteration, and they're all integers because that's what's in your list.
Secondly, you're not actually appending the squares to the list, you're just calculating the squares and doing nothing with them. Lastly, the sort method doesn't return anything, it just alters the list without returning a value. Use the equivalent sorted method which doesn't alter the list but does return a new value. I think you'll best understand with some code.
start_list = [5, 3, 1, 2, 4]
square_list = []
# for loop number is ambiguous variable
for number in start_list:
square = number ** 2 # calculate square to add later
square_list.append(square) # add the calculation
print sorted(square_list) # print sorted version

After loop your square_list is bound to integer [to be precise, it's value is 4].
To create list of squared numbers you may use list comprehensions:
square_list = [i**2 for i in start_list]
And then sort it:
square_list.sort()

Related

Adding a duplicate item on to a list

I'm trying to add the last item of a list onto the list my code is:
def dup_last(data):
data.append([-1])
return data
and calling for the function is:
item = dup_last([1,2,3])
print(item)
but I want my output to be within only one set of brackets like:
[1, 2, 3, 3]
data.append([-1])
Here you are appending [-1], a list with an element of -1, change it to:
data.append(data[-1])
In addition to other answers, I would also suggest to use slicing notation [:] when dealing with lists to prevent getting list index out of range errors in case there is no item:
def dup_last(data):
data.append(data[-1])
return data
The above function will raise IndexError if data is empty list:
>>> print dup_last([])
----> 2 data.append(data[-1])
3 return data
4
IndexError: list index out of range
When you update your function as follows, you no longer get that kind of error:
def dup_last(data):
data.extend(data[-1:])
return data
>>> print dup_last([])
[]
>>> print dup_last([1])
[1, 1]
>>> print dup_last([1, 2])
[1, 2, 2]
There is a good explanation in this SO question about how slicing works in Python.
You need to do data.append(data[-1]); data.append([-1]) appends a value which is a list containing only -1, so your result will be [1, 2, 3, [-1]].
Note that this will modify the list in-place, so whichever list you pass in will also have the last element duplicated, not just the list you get out (though they could be the same list).
I wouldn't use a function for this; just do data.append(data[-1]) instead of data = dup_last(data), or even dup_last(data). Also, it's probably better to just add the duplicate manually if you're working with a list literal; data = [1, 2, 3, 3] vs data = dup_last([1, 2, 3]) or similar.

Using for loop in Python 3.4 to remove particular element from array

As I am new to programming in Python. I am trying to remove particular elements from array using for loop which looks like
a=[2,3,1,4,1,1,1,5]
n=a.count(1)
for i in range (len(a)-n):
if (a[i]==1):
del a[i]
else:
a[i]=a[i]
print (a)
I want to remove 1 from array a. But, I am getting result as:
[2, 3, 4, 1, 1, 5].
That is 1 still exists in my new array. Can somebody please answer my problem?
try like this:
a = [2,3,1,4,1,1,1,5]
a = [x for x in a if x!=1] # this is called list comprehension
note Never modify list while iterating
Use a while loop and the remove method:
a = [2, 3, 1, 4, 1, 1, 1, 5]
while 1 in a:
a.remove(1)
print a
The real answer to your question (which none of the other answers addresses) is that every time you remove an item, the index i moves past it.
in your case:
a = [2,3,1,4,1,1,1,5]
after deleting the 5th item in the original list, the pointer moves to the 6th item, and the new 5th item (the second 1 in the sequence of three 1s) is skipped.
Regarding the comment never modify a list in a loop, try to implement an in-place algorithm like Fisher-Yates without modifying the list. Never say never. Know what you're doing.
The OP changes the list in-place, not creating a new list.
There are two methods, the second is safe, the first might be faster.
a = [2, 3, 1, 4, 1, 1, 1, 5]
toremove = 1
for i in range(len(a)-1, -1, -1):
if a[i] == toremove:
del a[i]
and
a = [2, 3, 1, 4, 1, 1, 1, 5]
toremove = 1
for i in range(a.count(toremove)):
a.remove(toremove)
The second removes the element however many times it exists (before the loop). Since we are not iterating on the list, it is safe to use the remove method.
Both fragments should be O(n) (but haven't done the calculations).
You can copy a and then remove but you cannot iterate over and delete elements from the same list, if your list starts with n elements python will have n pointers to each element so removing elements from the list as your are iterating over it will cause elements to be missed.python has no way of knowing you have removed elements from the list:
a = [2,3,1,4,1,1,1,5]
for ele in a[:]:
if ele == 1:
a.remove(1)
print(a)
[2, 3, 4, 5]
You can also use reversed which returns and iterator avoiding creating a whole copy of the list at once:
a = [2,3,1,4,1,1,1,5]
for ele in reversed(a):
if ele == 1:
a.remove(1)
print(a)
[2, 3, 4, 5]
Or using a list comprehension with the [:] syntax so we actually update the original object:
a[:] = (ele for ele in a if ele != 1)
All the above are linear operations using a single pass over a.
Actually as the del statement will remove elements from your list , and as the list that you bound in your loop doesn't been update after the first deleting you remove incorrect elements from your list , so if you want to use del you need to make the list name in your loop to reference to new list , that you can use a function for this aim , but as a more python way you can just use a list comprehension:
>>> a=[2,3,1,4,1,1,1,5]
>>> a=[i for i in a if i !=1]
>>> a
[2, 3, 4, 5]
Or you can use filter :
>>> a=[2,3,1,4,1,1,1,5]
>>> a=filter(lambda x: x !=1,a)
>>> a
[2, 3, 4, 5]

How do I print my list of numbers in python without "set" before it? With a function where it returns a new list & the numbers only occur once

I have defined a function that takes a list of numbers and returns a new list where each element of the first list only occurs once.
def unique(a):
return set(a)
print unique([1,2,3,4,1,5])
I tried print ",".join(str(e) for e in s) but it doesn't work because I have to print a new list where there is no repeated numbers.
You can use:
list(set(a))
This will convert the list to a set, which will keep only unique occurrences, then convert back to a list.
Example:
>>> list(set([1, 1, 2, 2, 3, 3]))
[1, 2, 3]

Reversing Order of List in Python

I have been given the following piece of code:
def two_pair(ranks):
"""If there are two pair, return the two ranks as a
tuple: (highest, lowest); otherwise return None."""
pair = kind(2,ranks)
lowpair = kind(2, list(reversed(ranks)))
if pair and lowpair != pair:
return (pair,lowpair)
else:
return None
In the lowpair variable, why does list() need to be stated? Why can't you just say reversed(ranks). ranks is a list. Is it not already implied?
reversed returns an iterator, not a list. We need to explicitly convert that to a list, unless we just want to iterate it.
a = [1, 2, 3]
print reversed(a) # <listreverseiterator object at 0x7fc57d746790>
That is why we have to use list to get the actual reversed list, like this
print list(reversed(a)) # [3, 2, 1]
If you want shorter code you could do ranks[::-1] instead of list(reversed(ranks)).
>>> ranks = [1,2,3]
>>> ranks[::-1]
[3, 2, 1]
reversed(ranks) isn't a reversed list. It's an iterator:
>>> reversed([1, 2, 3])
<listreverseiterator object at 0x0000000001DDE9E8>
The list call is necessary to get a reversed list.

Replace list number values with others?

I have this code
start_list = [5, 3, 1, 2, 4]
square_list = []
for number in start_list:
number = number**2
#I bet something should be added here but
#I have no idea what that would be
square_list.append(start_list[0])
square_list.append(start_list[1])
square_list.append(start_list[2])
square_list.append(start_list[3])
square_list.append(start_list[4])
square_list.sort()
print square_list
and I actually want to create a new list (the square_list) which includes the numbers of the start_list squared and sorted. This is my first day on python so be gentle!
Build a generator over the list producing your result, and feed it to sorted to get a list based on ascending value, eg:
start_list = [5, 3, 1, 2, 4]
square_list = sorted(n**2 for n in start_list)
# [1, 4, 9, 16, 25]
as I understand In your case it should looks like this:
start_list = [5, 3, 1, 2, 4]
square_list = []
for number in start_list:
number = number**2
square_list.append(number)
square_list.sort()
but You can use other methods
square_list = sorted(number**2 for number in start_list)
or
square_list = [number**2 for number in start_list]
square_list.sort()
Jon Clements' generator approach is the best and most pythonic way of doing this, however I think since you're a beginner it's worth understanding the for loop way of doing it. You've clearly understood the elements you need, you just need to plug them together in a new way.
start_list = [5, 3, 1, 2, 4]
square_list = []
for number in start_list:
All good so far, but you want to be adding these to square_list instead of doing number = number**2. Your code is simply modifying a temporary variable, rather than changing anything in place, assigning a new value to number won't change start_list. You want to this next:
square_list.append(number**2)
Then you just need to sort and print as you've already done
square_list.sort()
print(square_list)
(print without the brackets will work but it's being dropped with Python 3 so it's best to get used to using brackets now)

Categories