473,763 Members | 6,638 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Sorting troubles

I have the following implementations of quicksort and insertion sort:

def qSort(List):
if List == []: return []
return qSort([x for x in List[1:] if x< List[0]]) + List[0:1] + \
qSort([x for x in List[1:] if x>=List[0]])

def insertSort(List ):
for i in range(1,len(Lis t)):
value=List[i]
j=i
while List[j-1]>value and j>0:
List[j]=List[j-1]
j-=1
List[j]=value

Now, the quickSort does not modify the original list, mostly because
it works on products and concatenations, rather than alterations.
The insertion sort, however, does modify the list. Now, to give
results, they should be called in such a way( A is an unsorted list)
A=qSort(A)
# the insertion sort does not require this,
insertSort(A)

I would like to know how can I modify the qSort function such that it
affects the list directly inside
I have tried doing it like this

def qSort(List):
if List == []: return []
List = qSort([x for x in List[1:] if x< List[0]]) + List[0:1] + \
qSort([x for x in List[1:] if x>=List[0]])
return List

while processing, the list changes, but those changes remain inside
the function, so that once it's over, if nothis catches the return,
the original List remains unchanged.

If not a solution, I would like to at least know why it does what it
does. I so understand that List(above) is only a reference to the
actual data(a list), but I'm not passing a copy of the data to the
function, but the actual reference(hence , insertSort does
modifications). But then how can I change, inside the function, the
object List is referencing to? If I can't modify the original list,
maybe I can make the variable List point to another list? But changes
inside the function are local. Sorry if this is a bit confusing.

May 14 '07 #1
10 1223
On May 14, 11:05 am, seyens...@yahoo .com wrote:
I have the following implementations of quicksort and insertion sort:

def qSort(List):
if List == []: return []
return qSort([x for x in List[1:] if x< List[0]]) + List[0:1] + \
qSort([x for x in List[1:] if x>=List[0]])

def insertSort(List ):
for i in range(1,len(Lis t)):
value=List[i]
j=i
while List[j-1]>value and j>0:
List[j]=List[j-1]
j-=1
List[j]=value

Now, the quickSort does not modify the original list, mostly because
it works on products and concatenations, rather than alterations.
The insertion sort, however, does modify the list. Now, to give
results, they should be called in such a way( A is an unsorted list)
A=qSort(A)
# the insertion sort does not require this,
insertSort(A)

I would like to know how can I modify the qSort function such that it
affects the list directly inside
I have tried doing it like this

def qSort(List):
if List == []: return []
List = qSort([x for x in List[1:] if x< List[0]]) + List[0:1] + \
qSort([x for x in List[1:] if x>=List[0]])
return List

while processing, the list changes, but those changes remain inside
the function, so that once it's over, if nothis catches the return,
the original List remains unchanged.

If not a solution, I would like to at least know why it does what it
does. I so understand that List(above) is only a reference to the
actual data(a list), but I'm not passing a copy of the data to the
function, but the actual reference(hence , insertSort does
modifications). But then how can I change, inside the function, the
object List is referencing to? If I can't modify the original list,
maybe I can make the variable List point to another list? But changes
inside the function are local. Sorry if this is a bit confusing.
The thing is that [x for x in List[1:]...] is a brand new list created
by iterating over the old one.
How about:
qSortHelp(List) :
newlist = qSort(List)
for i, val in enumerate(newli st):
List[i] = val
You have to iterate over one more time, but this sorts the list in
place.
HTH,
Tom

May 14 '07 #2
On May 14, 12:05 pm, seyens...@yahoo .com wrote:
I have the following implementations of quicksort and insertion sort:

def qSort(List):
if List == []: return []
return qSort([x for x in List[1:] if x< List[0]]) + List[0:1] + \
qSort([x for x in List[1:] if x>=List[0]])

def insertSort(List ):
for i in range(1,len(Lis t)):
value=List[i]
j=i
while List[j-1]>value and j>0:
List[j]=List[j-1]
j-=1
List[j]=value

Now, the quickSort does not modify the original list, mostly because
it works on products and concatenations, rather than alterations.
The insertion sort, however, does modify the list. Now, to give
results, they should be called in such a way( A is an unsorted list)
A=qSort(A)
# the insertion sort does not require this,
insertSort(A)

I would like to know how can I modify the qSort function such that it
affects the list directly inside
I have tried doing it like this

def qSort(List):
if List == []: return []
List = qSort([x for x in List[1:] if x< List[0]]) + List[0:1] + \
qSort([x for x in List[1:] if x>=List[0]])
return List

while processing, the list changes, but those changes remain inside
the function, so that once it's over, if nothis catches the return,
the original List remains unchanged.

If not a solution, I would like to at least know why it does what it
does. I so understand that List(above) is only a reference to the
actual data(a list), but I'm not passing a copy of the data to the
function, but the actual reference(hence , insertSort does
modifications). But then how can I change, inside the function, the
object List is referencing to? If I can't modify the original list,
maybe I can make the variable List point to another list? But changes
inside the function are local. Sorry if this is a bit confusing.
It does what it does because in the return statement when you
concatenate qsort(...x<..)+ List[0:1]+qsort(...x>=.. ) you create a new
list. In the insertion sort you modify the values of the list directly
by doing List[j]=List[j-1] or List[j]=value.

If you just have to have the list modified in place, create another
wrapper function that calls your qsort and then will copy all data
from the result into the original list and you are done. Something
like:
def qsort_in_place( L):
sortedL=qsort(L )
for (i,x) in enumerate(sorte dL):
L[i]=x

Cheers,
-Nick Vatamaniuc

May 14 '07 #3
I see. I figured that list comprehensions made another list(duh), but
I thought I could relink the object(List) to the new list and keep it
once the function ended.

Is it possible to pass a reference(to an object.. Like 'List',
basically) to a function and change the reference to point to
something created inside a function? Or all data unreturned from a
function is lost and no references kept?(The second, I'd guess, since
it's local temporary scope, but you never know, maybe Python can :) )

May 14 '07 #4

<se*******@yaho o.comwrote in message
news:11******** **************@ h2g2000hsg.goog legroups.com...
|I have the following implementations of quicksort and insertion sort:
|
| def qSort(List):
| if List == []: return []
| return qSort([x for x in List[1:] if x< List[0]]) + List[0:1] + \
| qSort([x for x in List[1:] if x>=List[0]])
|
| def insertSort(List ):
| for i in range(1,len(Lis t)):
| value=List[i]
| j=i
| while List[j-1]>value and j>0:
| List[j]=List[j-1]
| j-=1
| List[j]=value
|
| Now, the quickSort does not modify the original list, mostly because
| it works on products and concatenations, rather than alterations.
| The insertion sort, however, does modify the list. Now, to give
| results, they should be called in such a way( A is an unsorted list)
| A=qSort(A)
| # the insertion sort does not require this,
| insertSort(A)
|
| I would like to know how can I modify the qSort function such that it
| affects the list directly inside
| I have tried doing it like this
|
| def qSort(List):
| if List == []: return []
| List = qSort([x for x in List[1:] if x< List[0]]) + List[0:1] + \
| qSort([x for x in List[1:] if x>=List[0]])
| return List
|
| while processing, the list changes, but those changes remain inside
| the function, so that once it's over, if nothis catches the return,
| the original List remains unchanged.
|
| If not a solution, I would like to at least know why it does what it
| does. I so understand that List(above) is only a reference to the
| actual data(a list), but I'm not passing a copy of the data to the
| function, but the actual reference(hence , insertSort does
| modifications). But then how can I change, inside the function, the
| object List is referencing to? If I can't modify the original list,
| maybe I can make the variable List point to another list? But changes
| inside the function are local. Sorry if this is a bit confusing.

The traditional way to do qsort in place (ignoring possible variations):

def qsort(List, start=0, stop=None):
if start >= stop: return
if stop == None: stop = len(List)
p = partition(List, start, stop) # p = index of pivot/partition item
qsort(List, start, p)
qsort(List, p+1, stop)

where partition puts elements less that pivot value before the pivot value
and greater values after.

You could instead call your function qSorted to indicate that it returns a
sorted copy ;-)

Terry Jan Reedy

May 14 '07 #5
se*******@yahoo .com wrote:
I see. I figured that list comprehensions made another list(duh), but
I thought I could relink the object(List) to the new list and keep it
once the function ended.

Is it possible to pass a reference(to an object.. Like 'List',
basically) to a function and change the reference to point to
something created inside a function? Or all data unreturned from a
function is lost and no references kept?(The second, I'd guess, since
it's local temporary scope, but you never know, maybe Python can :) )
Maybe this (untested):

def qsort(seq):
if seq:
pivot = seq.pop()
Q = L,R = [],[]
for x in seq:
Q[x>=pivot].append(x)
qsort(R)
seq[:] = L+[pivot]+R

A.
May 14 '07 #6
On Mon, 14 May 2007 09:49:56 -0700, Thomas Nelson wrote:
The thing is that [x for x in List[1:]...] is a brand new list created
by iterating over the old one.
How about:
qSortHelp(List) :
newlist = qSort(List)
for i, val in enumerate(newli st):
List[i] = val
You have to iterate over one more time, but this sorts the list in
place.
A better way of spelling that would be:

def qSortHelp(List) :
List[:] = qSort(List)
return List
but the helper function is redundant, as it is easy enough to make the
qSort function behave the same way. We can also make the code a smidgen
more concise by reversing the sense of the test at the start of the code:
def qSort(List):
if List:
List[:] = qSort([x for x in List[1:] if x< List[0]]) \
+ List[0:1] + qSort([x for x in List[1:] if x>=List[0]])
return List

--
Steven.
May 15 '07 #7
On May 15, 5:35 am, Steven D'Aprano
<ste...@REMOVE. THIS.cybersourc e.com.auwrote:
On Mon, 14 May 2007 09:49:56 -0700, Thomas Nelson wrote:
The thing is that [x for x in List[1:]...] is a brand new list created
by iterating over the old one.
How about:
qSortHelp(List) :
newlist = qSort(List)
for i, val in enumerate(newli st):
List[i] = val
You have to iterate over one more time, but this sorts the list in
place.

A better way of spelling that would be:

def qSortHelp(List) :
List[:] = qSort(List)
return List

but the helper function is redundant, as it is easy enough to make the
qSort function behave the same way. We can also make the code a smidgen
more concise by reversing the sense of the test at the start of the code:

def qSort(List):
if List:
List[:] = qSort([x for x in List[1:] if x< List[0]]) \
+ List[0:1] + qSort([x for x in List[1:] if x>=List[0]])
return List

--
Steven.
Ah, I see, just slicing it like that.. nice!
But after doing some timing tests, the version that's in place and
using partitions is about twice faster than the non hybrid qSort.
The hybrid one, with insertionsSort used for smaller lists works
faster, but in a weird way. When given lists of 2000, the best bet to
is to set the threshold to 14, but when given a list of 40000, 14 is
slow, but a threshold of 200(less or more is slower, again) makes it
about 8 times faster than a normal qSort, and 4 times faster than an
in-place qSort, using a self -defined partitioning alg.

Making a hybrid out of the in-place partitioned qSort makes it a bit
faster, but not by much compared to the other hybrid which uses list
comprehensions.

Teach said that the optimal threshold in hybrids is 14-16, but guess
he wasn't so right after all =\\ The overhead of using insertion sort
on a longer list turns out to be faster than just piling on
recursions, when confronted with bigger lists.

I should probably try and make it iterative now, see how it goes.
Gonna need a stack though, I think.

Thanks for all the answers up to now! :)

May 15 '07 #8

<se*******@yaho o.comwrote in message
news:11******** *************@q 75g2000hsh.goog legroups.com...
| Teach said that the optimal threshold in hybrids is 14-16, but guess
| he wasn't so right after all =\\ The overhead of using insertion sort
| on a longer list turns out to be faster than just piling on
| recursions, when confronted with bigger lists.

The current list.sort (is C, of course, not Python) is a hybrid
insert/merge sort with a threshhold, last I knew, of 64. I believe there
are explanatory comments in the source.

tjr

May 15 '07 #9
On Mon, 14 May 2007 21:45:26 -0700, seyensubs wrote:
Ah, I see, just slicing it like that.. nice! But after doing some timing
tests, the version that's in place and using partitions is about twice
faster than the non hybrid qSort. The hybrid one, with insertionsSort
used for smaller lists works faster, but in a weird way. When given
lists of 2000, the best bet to is to set the threshold to 14, but when
given a list of 40000, 14 is slow, but a threshold of 200(less or more
is slower, again) makes it about 8 times faster than a normal qSort, and
4 times faster than an in-place qSort, using a self -defined
partitioning alg.

Making a hybrid out of the in-place partitioned qSort makes it a bit
faster, but not by much compared to the other hybrid which uses list
comprehensions.

Teach said that the optimal threshold in hybrids is 14-16, but guess he
wasn't so right after all =\\ The overhead of using insertion sort on a
longer list turns out to be faster than just piling on recursions, when
confronted with bigger lists.
Teach may have been thinking of languages where comparing items is fast
and moving data is slow; Python is the opposite, comparisons invoke a
whole bucket-full of object-oriented mechanism, while moving data just
means moving pointers.

It needs to be said, just in case... this is a good learning exercise,
but don't use this in real code. You aren't going to get within a bull's
roar of the performance of the built-in sort method. Tim Peter's
"timsort" is amazingly powerful; you can read about it here:

http://pythonowns.blogspot.com/2002_....html#79780508

http://svn.python.org/projects/pytho...s/listsort.txt

--
Steven.
May 15 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
2533
by: dont bother | last post by:
This is really driving me crazy. I have a dictionary feature_vectors{}. I try to sort its keys using #apply sorting on feature_vectors sorted_feature_vector=feature_vectors.keys() sorted_feature_vector.sort() #feature_vector.keys()=sorted_feature_vector
3
2887
by: Philipp Lenssen | last post by:
I have this XML file which I would like to XSLT-sort based on the string contained within the item-children elements using basic MSXML (no recent version of IIS, so it might be an outdated MSXML -- pretty sure not MSXML4, though tips on how to do it with that are appreciated too): ----------- Translation Dictionary (German) ---- <?xml version="1.0" encoding="iso-8859-1"?> <items> <item id="4">
1
2312
by: Abhijit Bhadra | last post by:
Hi , In C++ , I have some files as per their date of creation . The files are in the form of maple01012005.log maple01142005.log maple01202005.log sample01182005.log
3
1840
by: Robert | last post by:
I am trying to sort a column of numbers in a large . How do I build my query? Thanx Example: 11 2 3 2 55 9
1
1784
by: news.microsoft.com | last post by:
<asp:Repeater id="rptCourseDetail2" runat="server" datasource='<%# ((DataRowView)Container.DataItem).Row.GetChildRows("CourseDetailRelation") %>' EnableViewState="false" > I am having troubles trying to sort child records that appear in a repeater..... Above is the code that i use for the BINDIng...
1
7189
KevinADC
by: KevinADC | last post by:
Introduction In part one we discussed the default sort function. In part two we will discuss more advanced techniques you can use to sort data. Some of the techniques might introduce unfamiliar methods or syntax to a less experienced perl coder. I will post links to online resources you can read if necessary. Experienced perl coders might find nothing new or useful contained in this article. Short Review In part one I showed you some...
77
3371
by: arnuld | last post by:
1st I think of creating an array of pointers of size 100 as this is the maximum input I intend to take. I can create a fixed size array but in the end I want my array to expand at run-time to fit the size of input. I am not able to come up with anyting all all and doing: char* arr_of_pointers; seems like a completely wrong idea as this is a static array. I want to take the input and then decide how much memory I need and then malloc...
7
20038
Plater
by: Plater | last post by:
I am having trouble determining when my DataGridView object is sorting (based on a column header click). The idea is, in a large table, sorting the columns takes time, so I show a splash screen. When it is done sorting I want the splash screen dissapear. What I had been doing was using the CellClick and Sorted events: private void myDGV_CellClick(object sender, DataGridViewCellEventArgs e) { if (e.RowIndex == -1) {//sorting
5
4955
by: jrod11 | last post by:
hi, I found a jquery html table sorting code i have implemented. I am trying to figure out how to edit how many colums there are, but every time i remove code that I think controls how many colums there are, it crashes. There are currently 6 columns, and I only want 4. How do I remove the last two (discount and date)? Here is a link: http://www.jaredmoore.com/tablesorter/docs/salestable.html Here is some jquery js that I think...
3
1924
by: danglez | last post by:
well I have a template of a structure...but when I try to add something to sort the list (an attempt at a bubble sort), I'm running into some problems....any input would be appreciated, thanks this is all inside of a struct a (program runs and user have 2 options of either entering a new item, and sorting that listed items...the entering a new item part I'm done but the sorting I'm having some trouble) the errors that come up "invalid...
0
9387
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10002
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9823
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8822
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7368
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5270
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5406
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3917
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3528
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.