I would like to form a list by adding numbers one by one. When numbers is added, the list will be sorted by ascending. For this reason, I wrote codes as below but when I execute these codes, the order of numbers in the list become as I added. What is wrong with these codes?
class SortList:
theList = []
theempty = []
def sorttheList(self,number):
self.theempty.append(number)
for i in range(len(self.theempty)):
mini = min(self.theempty)
self.theList.append(mini)
self.theempty.remove(mini)
return self.theList
def printList(self):
return print(self.theList)
lst = SortList()
lst.sorttheList(2)
lst.sorttheList(4)
lst.sorttheList(9)
lst.sorttheList(15)
lst.sorttheList(0)
lst.printList()
theempty only ever has the last value passed to sorttheList, so that is always appended to the end of theList.
You might be better off using Python's built-in sorting methods.
Related
I have a function that I found that sorts a list of files strings by number. I found this on the internet and it works great. But, I want to simply it so it's not all done on one line, and it's more readable for other people. But, I'm having a difficult time doing this because I don't understand the sorted function key, and lambda's very well. Any help would be greatly appreciated.
Input
input_list = ['file_stuff_1','file_stuff_23','file_stuff_4','file_stuff_6']
Code
output = sorted(input_list, key=lambda x: int("".join([i for i in x if i.isdigit()])))
Output
['file_stuff_1','file_stuff_4','file_stuff_6','file_stuff_23']
Attempt
This was my first attempt at it. But I'm not sure how to fix digits so it works as a key.
def sort_list(input_list):
for item in input_list:
if (item.isdigit()):
digits = int(''.join(item))
output = sorted(input_list,digits)
return output
def get_nums_from_filename(file_name):
digits = [char for char in file_name if char.isdigit()]
return int(''.join(digits))
input_list = ['file_stuff_1','file_stuff_23','file_stuff_4','file_stuff_6']
sorted(input_list, key=get_nums_from_filename)
https://docs.python.org/3/howto/sorting.html#key-functions
the "key" param in sorted() specifies a function that should be applied to each item to get a resulting value, then sorting of the original values is done based on the corresponding resulting values.
I'm a computing student who posted a question here the other day about helping me with my function to sort scores in order and I got some great help and it now works but I would also like it to sort the names according to the scores (so if James gets 10 then it prints "James 10". Right now what is happening is that the scores are sorting and printing to the screen properly but the names are just printing in the order that they are entered. I've tried this:
def sortlist():
global scorelist, namelist, hss
namelist = []
scorelist = []
hs = open("hstname.txt", "r")
namelist = hs.read().splitlines()
hss = open("hstscore.txt","r")
for line in hss:
scorelist.append(int(line))
switched = True
while switched:
switched = False
for i in range(len(scorelist)-1):
for j in range(len(namelist)-1):
if scorelist[i] < scorelist[i+1]:
scorelist[i],scorelist[i+1] = scorelist[i+1],scorelist[i]
namelist[j],namelist[j+1] = namelist[j+1],namelist[j]
switched = True
The score part works fine and it took me ages to get it and I'm not allowed to use a pre defined function like .sort(). Can anyone offer any help/advice? Or if you can see what I'm doing wrong then can you offer a solution? I can't work this out for the life of me
You don't need to use nested loops in order to go through both lists.
Since you should be manipulating the two lists in exactly the same way, you should only be using one for loop, and using the i variable to index into both lists.
If yoy turn this:
for i in range(len(scorelist)-1):
for j in range(len(namelist)-1):
if scorelist[i] < scorelist[i+1]:
scorelist[i],scorelist[i+1] = scorelist[i+1],scorelist[i]
namelist[j],namelist[j+1] = namelist[j+1],namelist[j]
switched = True
into this:
for i in range(len(scorelist)-1):
if scorelist[i] < scorelist[i+1]:
scorelist[i],scorelist[i+1] = scorelist[i+1],scorelist[i]
namelist[i],namelist[i+1] = namelist[i+1],namelist[i]
switched = True
then you should get both lists sorted as you want them.
The only time when this will cause an error is if your two lists are of different lengths. If namelist is somehow shorter than scorelist then this code will throw an exception. You could guard against that by checking before your sort routine that
len(scorelist) == len(namelist)
Imagine, you have a function that returns a single sorted list e.g. here's an implementation of Quicksort algorithm in Python:
def qsorted(L):
return L and (qsorted([x for x in L[1:] if x < L[0]]) + # lesser items
[L[0]] + # pivot
qsorted([x for x in L[1:] if x >= L[0]])) # greater or equal
Then you could use it to sort your scorelist:
qsorted_scorelist = qsorted(scorelist)
To sort namelist according to the order of scorelist; you could use Schwartzian transform:
qsorted_namelist = [name for score, name in qsorted(zip(scorelist, namelist))]
Note that the same function qsorted() is used in both case: to sort the scorelist along and to sort both lists together. You should try to extract common functionality into separate functions instead of modifying your sorting algorithm inplace for a slighty different task.
To test that the result is correct; you could use the builtin sorted() function:
sorted_namelist = [name for score, name in sorted(zip(scorelist, namelist))]
I'm a student in a Computing class and we have to write a program which contains file handling and a sort. I've got the file handling done and I wrote out my sort (it's a simple sort) but it doesn't sort the list. My code is this:
namelist = []
scorelist = []
hs = open("hst.txt", "r")
namelist = hs.read().splitlines()
hss = open("hstscore.txt","r")
for line in hss:
scorelist.append(int(line))
scorelength = len(scorelist)
for i in range(scorelength):
for j in range(scorelength + 1):
if scorelist[i] > scorelist[j]:
temp = scorelist[i]
scorelist[i] = scorelist[j]
scorelist[j] = temp
return scorelist
I've not been doing Python for very long so I know the code may not be efficient but I really don't want to use a completely different method for sorting it and we're not allowed to use .sort() or .sorted() since we have to write our own sort function. Is there something I'm doing wrong?
def super_simple_sort(my_list):
switched = True
while switched:
switched = False
for i in range(len(my_list)-1):
if my_list[i] > my_list[i+1]:
my_list[i],my_list[i+1] = my_list[i+1],my_list[i]
switched = True
super_simple_sort(some_list)
print some_list
is a very simple sorting implementation ... that is equivelent to yours but takes advantage of some things to speed it up (we only need one for loop, and we only need to repeat as long as the list is out of order, also python doesnt require a temp var for swapping values)
since its changing the actual array values you actually dont even need to return
I want a function to return me the value of the equation for every number in the list. I have a list of 24 parameters, and I need to solve an equation for every value of this list.
This is the way I get my list:
wlist=[]
def w(i):
for i in range(24):
Calctruesolar=((i*60/1440)*1440+eq_time()+4*long-60*timezone)%1440
if Calctruesolar/4<0:
Calcw=(Calctruesolar/4)+180
wlist.append(Calcw)
print(Calcw)
else:
Calcw=(Calctruesolar/4)-180
wlist.append(Calcw)
print(Calcw)
Then, the list is this one:
>>> wlist=
[166.24797550450222, -178.75202449549778, -163.75202449549778, -148.75202449549778, -133.75202449549778, -118.75202449549778, -103.75202449549778, -88.75202449549778, -73.75202449549778, -58.75202449549778, -43.75202449549778, -28.75202449549778, -13.752024495497778, 1.2479755045022216, 16.24797550450222, 31.24797550450222, 46.24797550450222, 61.24797550450222, 76.24797550450222, 91.24797550450222, 106.24797550450222, 121.24797550450222, 136.24797550450222, 151.24797550450222]
Now, I use the next function:
def hourly_radiation(wlist):
for i in wlist:
Calcrt=(math.pi/24)*(a()+b()*math.cos(math.radians(i)))*((math.cos(math.radians(i)))-math.cos(math.radians(wss())))/(math.sin(math.radians(wss()))-((math.pi*wss()/180)*math.cos(math.radians(wss()))))
CalcI=Calcrt*radiation
print(Calcrt,CalcI)
So, I want to receive Calcrt and CalcI for every value inside the list. But it doesn't work. I have been looking for information in internet and tutorials but I didn't find anything.
Try this:
def hourly_radiation(wlist):
rt_list = []
I_list = []
for i in wlist:
Calcrt = (math.pi/24)*(a()+b()*math.cos(math.radians(i)))*((math.cos(math.radians(i)))-math.cos(math.radians(wss())))/(math.sin(math.radians(wss()))-((math.pi*wss()/180)*math.cos(math.radians(wss()))))
CalcI = Calcrt*radiation
rt_list.append(Calcrt)
i_list.append(CalcI)
print(Calcrt,CalcI)
dict = {}
dict["Calcrt"] = rt_list
dict["CalcI"] = i_list
return dict
This would return the values as a dictionary containing two lists. You may use any data structure that matches your requirements.
You may also create a tuple in each loop run and append it to a list and return it, like:
def hourly_radiation(wlist):
rt_list = []
data = ()
for i in wlist:
Calcrt = (math.pi/24)*(a()+b()*math.cos(math.radians(i)))*((math.cos(math.radians(i)))-math.cos(math.radians(wss())))/(math.sin(math.radians(wss()))-((math.pi*wss()/180)*math.cos(math.radians(wss()))))
CalcI = Calcrt*radiation
data = (Calcrt, CalcI)
print(Calcrt, CalcI)
rt_list.append(data)
return rt_list
I have not run or tested this code, but I hope it should work.
Please use this as a starting point and not as a copy-paste solution.
i ran into a little logic problem and trying to figure it out.
my case is as follows:
i have a list of items each item represents a Group
i need to create a set of nested groups,
so, for example:
myGroups = ["head", "neck", "arms", "legs"]
i need to get them to be represented like this:
(if you can imaging a folder structure)
head
|_> neck
|_> arms
|_>legs
and so on until i hit the last element.
what i thought would work (but don't know really how to advance here) is:
def createVNTgroups(self, groupsData):
for i in range(len(groupsData)):
print groupsData[i]
for q in range(1, len(groupsData)):
print groupsData[q]
but in this case, i am running over same elements in 'i' that i already took with 'q'.
could someone give me a hint?
thanks in advance!
If I understood well, you want a nested structure. For this case, you can use a recursive function:
myGroups = ["head", "neck", "arms", "legs"]
def createVNTgroups(alist):
temp = alist[:] # needed because lists are mutable
first = [temp.pop(0)] # extract first element from list
if temp: # if the list still contains more items,
second = [createVNTgroups(temp)] # do it recursively
return first + second # returning the second object attached to the first.
else: # Otherwise,
return first # return the last element
print createVNTgroups(myGroups)
this produces a nested list:
['head', ['neck', ['arms', ['legs']]]]
Is that what you were looking for?
>>> m
['head', 'neck', 'arms', 'legs']
>>> reduce(lambda x,y:[x,y][::-1] if x!=y else [x], m[::-1],m[-1])
['head', ['neck', ['arms', ['legs']]]]