前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >并不简单的问题:列表与元祖有什么区别?

并不简单的问题:列表与元祖有什么区别?

作者头像
Python猫
发布2019-04-10 10:07:28
7100
发布2019-04-10 10:07:28
举报
文章被收录于专栏:Python无止境Python无止境

花下猫说:公众号没有留言功能,真是不方便。上周,尝试性地推送了一篇英文文章,单从后台数据来看,效果还不错。这周继续尝试推送一篇。大家有什么想法,可以后台与我交流。

PS:前一篇荐书《黑客与画家》,有一个抽奖,截止时间是11月09日 18:18。为了好玩,我设了一个特别简单的题目,真没想到的是,有几个小伙伴回复了错得离谱的答案……唉,那我也没办法了。友情提示一下,本号粉丝少,目前参与人数更是少,中奖概率特别大,没参加的抓紧机会。参与方式在前一篇荐书里。


原标题:《Lists vs. Tuples》 作者:Ned Batchelder 原文链接:http://t.cn/EwgkNrg

A common beginner Python question: what’s the difference between a list and a tuple?

The answer is that there are two different differences, with complex interplay between the two. There is the Technical Difference, and the Cultural Difference.

First, the things that are the same: both lists and tuples are containers, a sequence of objects:

代码语言:javascript
复制
>>> my_list = [1, 2, 3]
>>> type(my_list)<class 'list'>
>>> my_tuple = (1, 2, 3)
>>> type(my_tuple)<class 'tuple'>

Either can have elements of any type, even within a single sequence. Both maintain the order of the elements (unlike sets and dicts).

Now for the differences. The Technical Difference between lists and tuples is that lists are mutable (can be changed) and tuples are immutable (cannot be changed). This is the only distinction that the Python language makes between them:

代码语言:javascript
复制
>>> my_list[1] = "two"
>>> my_list[1, 'two', 3]
>>> my_tuple[1] = "two"
>>> Traceback (most recent call last):  File "<stdin>", line 1, in <module>
    TypeError: 'tuple' object does not support item assignment

That’s the only technical difference between lists and tuples, though it manifests in a few ways. For example, lists have a .append() method to add more elements to the list, while tuples do not:

代码语言:javascript
复制
>>> my_list.append("four")
>>> my_list[1, 'two', 3, 'four']
>>> my_tuple.append("four")Traceback (most recent call last):  File "<stdin>", line 1, in <module>
    AttributeError: 'tuple' object has no attribute 'append'

Tuples have no need for an .append() method, because you can’t modify tuples.

The Cultural Difference is about how lists and tuples are actually used: lists are used where you have a homogenous sequence of unknown length; tuples are used where you know the number of elements in advance because the position of the element is semantically significant.

Another way to say it: a list is an arbitrary number of similar things; a tuple is one thing with a known number of (possibly dissimilar) parts.

For example, suppose you have a function that looks in a directory for files ending with *.py. It should return a list, because you don’t know how many you will find, and all of them are the same semantically: just another file that you found.

代码语言:javascript
复制
>>> find_files("*.py")
>>> ["control.py", "config.py", "cmdline.py", "backward.py"]

On the other hand, let’s say you need to store five values to represent the location of weather observation stations: id, city, state, latitude, and longitude. A tuple is right for this, rather than a list:

代码语言:javascript
复制
>>> denver = (44, "Denver", "CO", 40, 105)
>>> denver[1]'Denver'

(For the moment, let’s not talk about using a class for this.) Here the first element is the id, the second element is the city, and so on. The position determines the meaning.

To put the Cultural Difference in terms of the C language, lists are like arrays, tuples are like structs.

Python has a namedtuple facility that can make the meaning more explicit:

代码语言:javascript
复制
>>> from collections import namedtuple
>>> Station = namedtuple("Station", "id, city, state, lat, long")
>>> denver = Station(44, "Denver", "CO", 40, 105)
>>> denverStation(id=44, city='Denver', state='CO', lat=40, long=105)
>>> denver.city'Denver'
>>> denver[1]'Denver'

One clever summary of the Cultural Difference between tuples and lists is: tuples are namedtuples without the names.

The Technical Difference and the Cultural Difference are an uneasy alliance, because they are sometimes at odds. Why should homogenous sequences be mutable, but hetergenous sequences not be? For example, I can’t modify my weather station because a namedtuple is a tuple, which is immutable:

代码语言:javascript
复制
>>> denver.lat = 39.7392
>>> Traceback (most recent call last):  File "<stdin>", line 1, in <module>
    AttributeError: can't set attribute

And sometimes the Technical considerations override the Cultural considerations. You cannot use a list as a dictionary key, because only immutable values can be hashed, so only immutable values can be keys. To use a list as a key, you can turn it into a tuple:

代码语言:javascript
复制
>>> d = {}
>>> nums = [1, 2, 3]
>>> d[nums] = "hello"
>>> Traceback (most recent call last):  File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'list'
>>> d[tuple(nums)] = "hello"
>>> d{(1, 2, 3): 'hello'}

Another conflict between the Technical and the Cultural: there are places in Python itself where a tuple is used when a list makes more sense. When you define a function with *args, args is passed to you as a tuple, even though the position of the values isn’t significant, at least as far as Python knows. You might say it’s a tuple because you cannot change what you were passed, but that’s just valuing the Technical Difference over the Cultural.

I know, I know: in *args, the position could be significant because they are positional parameters. But in a function that’s accepting *args and passing it along to another function, it’s just a sequence of arguments, none different from another, and the number of them can vary between invocations.

Python uses tuples here because they are a little more space-efficient than lists. Lists are over-allocated to make appending faster. This shows Python’s pragmatic side: rather than quibble over the list/tuple semantics of *args, just use the data structure that works best in this case.

For the most part, you should choose whether to use a list or a tuple based on the Cultural Difference. Think about what your data means. If it can have different lengths based on what your program encounters in the real world, then it is probably a list. If you know when you write the code what the third element means, then it is probably a tuple.

On the other hand, functional programming emphasizes immutable data structures as a way to avoid side-effects that can make it difficult to reason about code. If you are a functional programming fan, you will probably prefer tuples for their immutability.

So: should you use a tuple or a list? The answer is: it’s not always a simple answer.

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-11-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python猫 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档