Suggestion: make sequence and map interfaces more similar

Steven D'Aprano steve at pearwood.info
Sat Mar 26 07:41:58 EDT 2016


On Sat, 26 Mar 2016 11:18 am, Marco Sulla wrote:

>> That's a very superficial similarity: a list ['a', 'b', 'x', 'y'] is
>> something like a mapping {0: 'a', 1: 'b', 2: 'x', 3: 'y'}. Seems logical,
>> since in both cases we write collection[2] and get 'x' back.

Marco, it is considered polite to give attribution to the person you are
quoting. In this case, that would be me. But it is still polite to say so.


>> But think about it a bit more, and you will see that the behaviour is in
>> fact *very different*. For example:
>>
>> the_list = ['a', 'b', 'x', 'y']
>> # the_list is equivalent to {0: 'a', 1: 'b', 2: 'x', 3: 'y'}
>> the_list.insert(0, 'z')
>> # the_list is now equivalent to {0: 'z', 1: 'a', 2: 'b', 3: 'x', 4: 'y'}
>>
>> Every existing "key:value" pair has changed! What sort of mapping
>> operates like that?
> 
> It's like you said: "Animals with four legs can usually run, eat etc. But
> birds can fly! What sort of animal flies?"
> Well. birds.

Er... okay. What's that got to do with what we are discussing?


The point you might have missed is that treating lists as if they were
mappings violates at least one critical property of mappings: that the
relationship between keys and values are stable.

Consider a simple address book, mapping between (let's say) a person's name
and their address:

address_book = {
    'Fred': '123 Smiths Road',
    'Ishmael': '37a Penny Lane',
    'Jane': '2019 Short Street',
    'Sam': '48 Main Road',
    }

Now we add a new item:

address_book['Annette'] = '97 The Boulevard'

and then retrieve Jane's address. With a real mapping, like dict, then we
know what will happen:

print(address_book['Jane'])
=> prints '2019 Short Street'


Adding or deleting entries in a mapping does not affect the remaining
key:value pairs. It is absolutely critical and fundamental to mappings that
the key:value pairs are stable.

But suppose we had a mapping which lacked that stability:


print(address_book['Jane'])  # fundamentally broken mapping
=> prints '37a Penny Lane'   # the address has mysteriously changed


Do you think this would be reasonable behaviour for a mapping? I hope you
would say "No".


Now, let's imagine that we treat lists as if they were mappings, where the
index is the key:

address_book = [
    '123 Smiths Road',    # key = 0, Fred
    '37a Penny Lane',     # key = 1, Ishmael
    '2019 Short Street',  # key = 2, Jane
    '48 Main Road',       # key = 3, Sam
    ]


Now we add a new item:

address_book.insert(0, '97 The Boulevard')  # Annette

and retrieve Jane's address, using Jane's "key":

print(address_book[2])
=> prints '37a Penny Lane'


This is exactly the behaviour which (I hope) we have agreed would be broken
for a dict or other mapping. We do not have stability of "key":value pairs.
This violates the property that mapping key:value pairs should be stable.
Inserting new entries into a mapping, or deleting them, shouldn't affect
the remaining entries. But with a sequence, it can effect the relationship
between index and item.

That means that indexes are not keys, and sequences are not mappings.

For a sequence, this does not matter. There is no promise that items will
always be found at the same index you put them in. Many operations on
sequences will move items around:

sort
reverse
pop
insert
delete an item or slice
some slice assignments
shuffle

and more.




-- 
Steven




More information about the Python-list mailing list