问题
Note: I am using python 3.
I am trying to sort a list of words in alphabetical order.
This is my sort:
def radix_sort(List, length):
buckets = [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
for i in range (length-1, -1, -1): #for every letter "column"
for word in List: #for every word
index = ord(word.azWord[i])-ord('a') #get the index of the word
buckets[index].append(word) #add word object to correct bucket
List[:] = []
for containedList in buckets:
List.extend(containedList)
It is being used in this loop:
for x in range(0,maxL):
radix_sort(results[x], x)
maxL is the length of the longest words I have, so iterating from 0 to maxL goes through the entire list.
My list results[] is a list of lists. Each list within results contains a word object described as follows:
class word(object): #object class
def __init__(self, originalWord=None, azWord=None, wLength=None):
self.originalWord = originalWord
self.azWord = azWord
self.wLength = wLength
For example, results[3] should contain a list of all words with wLength of 3.
When I feed my entire program the following input:
hello
world
alphabetical
dog
cat
potato
stack
With this piece of code:
for row in results:
for item in row:
print(item.originalWord)
It prints:
cat
cat
dog
dog
dog
cat
stack
stack
world
hello
hello
stack
hello
hello
world
hello
world
world
stack
stack
world
potato
potato
potato
potato
potato
potato
alphabetical
I'm pretty sure I'm iterating through results[] correctly when printing. Why is my radix_sort not giving me the right results? I tried using the debugger but no luck.
EDIT: I changed my code to be as follows:
def radix_sort(List, length):
for i in range (length-1, -1, -1):
for word in List:
buckets = [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
index = ord(word.azWord[i])-ord('a')
buckets[index].append(word)
List[:] = []
for containedList in buckets:
List.extend(containedList)
return List #returns an alphabetized list
Now it's giving me an error here:
for containedList in buckets:
It says "UnboundLocalError: local variable 'buckets' referenced before assignment". What does this mean?
回答1:
Following on my comments, that should look like
def radix_sort(List, length):
for i in range (length-1, -1, -1): #for every letter "column"
# Here buckets are created for each iteration
buckets = [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
for word in List: #for every word
index = ord(word.azWord[i])-ord('a') #get the index of the word
buckets[index].append(word) #add word object to correct bucket
# Here List is reconstructed for each iteration
List[:] = []
for containedList in buckets:
List.extend(containedList)
回答2:
for i in range (length-1, -1, -1): #for every letter "column"
for word in List: #for every word
index = ord(word.azWord[i])-ord('a') #get the index of the word
buckets[index].append(word) #add word object to correct bucket
Let's take a look at this code. On the first iteration of the outer loop, you put all the words in the buckets. On the second iteration, you put all the words in the buckets again. That happens again and again on every further iteration; only once you're all done do you take the words out of the buckets and put them back in the original list.
In radix sort, when you sort, you need to create a fresh set of buckets on every iteration of the outer loop. Every time you finish putting the items in the buckets, you need to reorder the list using the buckets, rather than doing that only at the very end.
回答3:
Use a list comprehension when making your queue. This will make your code easier to read, as nobody wants to count all those empty bins.
buckets = [[] for i in range(26)]
Also, another way to get the bucket index, instead of assigning a variable, just put those calculations in the index.
buckets[((ord(letter)/10**i)%10) for letter in word]
来源:https://stackoverflow.com/questions/22844711/what-is-wrong-with-my-radix-sort