What is the method of order for sorting the addresses?

Though reading again and again the solution of exercise 1 & 2 about addresses, I cannot clarify how this solution came up. For example, why ‘1600 Pennsylvania Ave’ is sorted before '221 B Baker St. and then the ‘742 Evergreen Terrace’ follows ? Which criterion was used , either numerical or alphabetical?
Additionally, to extend my previous question, when a list contains items which are not individually categorised as numbers or strings but they are actually “mixed” (like addresses), how does .sort() work?
I read in the lesson, the top question (and answer) about the way sort() function work if a list contains different data types, however I am asking something slightly different as I refer to different data types “inside” each item.

2 Likes

Think of every printable character as being ordered from lowest to highest. As we can see, Upper case comes before lower case,

A => 65
a => 97

Numbers are also printable characters that precede the alpha letters.

0 => 48
9 => 57

Sorting follows left to right, ascending (in the normal sense). ‘0’ will come before ‘A’, ‘1’ before ‘7’, &c.

1600 -> 221 -> 742

The criterion used is as we described, ordinal.

18 Likes

When applied to the list of addresses, the sort function orders them in a way that is not alphabetical. Why? What logic does the sorted order follow?

1 Like

Please show us the order in which they were sorted.

1 Like

See mtf’s previous post: Note that all uppercase letters are “less” than all lowercase letters. Digits and punctuation have their own ranges. If you need your code to alphabetize a list according to a strict schema, you must take those things into account; Python’s “lexicographical order” by itself won’t do it for you…

3 Likes

Sorting is pretty straightforward regarding numbers. With words, lexicographical order is complicated a bit concerning comparison between uppercase and lowercase letters, as @patrickd314 has mentioned.

Ideally, addresses should be implemented as a class. Then, a __lt__ method could be defined for that class, and that would determine the sorting order. See Data model: object. __lt__ ( self , other ).

As a simple extension of the current exercise, we could define a key function to govern the sorting order of the addresses. We can sort by the street name first, then by house number. See Sorting HOW TO. Following is an example:

# enhanced addresses list
addresses = ['123 Downing St.',
             '17 Downing St.',
             '221 B Baker St.',
             '42 Wallaby Way',
             '42 Wallaby Ave',
             '12 Grimmauld Place',
             '742 Evergreen Terrace',
             '1600 Pennsylvania Ave',
             '10 Downing St.']

def address_key_maker(address):
    # defines key for addresses list sorting order
    first_space_index = address.index(" ")
    number_str = str(address[:first_space_index])
    street = address[first_space_index + 1:].lower()
    return (street, int(number_str))

# sort addresses list, using the key
addresses.sort(key=address_key_maker)

# demonstrate how addresses list was sorted
for address in addresses:
    print(address)

Output:

221 B Baker St.
10 Downing St.
17 Downing St.
123 Downing St.
742 Evergreen Terrace
12 Grimmauld Place
1600 Pennsylvania Ave
42 Wallaby Ave
42 Wallaby Way

There is still a complication here. In 221 B Baker St., the house number should really be 221 B, but the code places that first B within the name of the street. Implementing an Address class that explicitly breaks the address into components could rectify that issue, as well as bring other geographic entities into the address.

6 Likes

Good Morning Mr MTF

I didn’t get it your explanation. How could ‘1600 Pennsylvania Ave’ comes first than ‘221 B Baker St’? If the criteria is numerical 221 comes first than 1600 in ascending order and so on. On the other hand if the criteria is alphabetical “B” comes first than “P”. Therefore I didn’t understand the result of this exercise. Can you please make this clear?

It seems there is no criteria to put a list in order when we use sort() for addresses.

Also if I want to assign cities to a variable how can I print in ascending order using sort()? Or I can’t use this in a variable?

cities = [‘London’, ‘Paris’, ‘Rome’, ‘Los Angeles’, ‘New York’]

sorted_cities = cities.sort()

print(???)

Tks in advance

The order is determined at the character level. 1 comes before 2.

1 Like

Tks a lot @mtf now I got it.

Have a good day.

1 Like

Hey @mtf,

I have a question, I am revisiting some courses and there is something I don’t understand.

When I use this code, my list gets sorted.

### Exercise 3 ###
names = ['Ron', 'Hermione', 'Harry', 'Albus', 'Sirius']
names.sort()
print(names)
### Exercise 4 ###
cities = ["Alabama",'London', 'Paris', 'Rome', 'Los Angeles', 'New York']

cities.sort(reverse=True)
print(cities)

But when I use the sort method on a list and assign it to a variable I get as output “None”
Do you know why this happens?

Here is an example.

### Exercise 1 & 2 ###
addresses = ['221 B Baker St.', '42 Wallaby Way', '12 Grimmauld Place', '742 Evergreen Terrace', '1600 Pennsylvania Ave', '10 Downing St.']

# Sort addresses here:
a=addresses.sort()
print(a)

Yes. It is because of the nature of in-place operations as opposed to stored operations that can be returned. The former cannot be returned, hence, None.

We can achieve what you are after using the sorted() function rather than the .sort() method.

a = sorted(addresses)

The original list is unchanged since this function creates a copy then sorts it. That is what is returned.

1 Like