Lists
Lists
在Python中,Lists(列表)表示值的有序序列,下面是一个如何构建它们的例子:
primes = [2, 3, 5, 7]
我们可以把其他类型的东西放在列表中:
planets = ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
我们甚至可以列一个列表的列表:
hands = [
['J', 'Q', 'K'],
['2', '2', '2'],
['6', 'A', 'K'], # (Comma after the last element is optional)
]
# (I could also have written this on one line, but it can get hard to read)
hands = [['J', 'Q', 'K'], ['2', '2', '2'], ['6', 'A', 'K']]
列表可以包含不同类型变量的混合:
my_favourite_things = [32, 'raindrops on roses', help]
# (Yes, Python's help function is *definitely* one of my favourite things)
Indexing
您可以访问带有方括号的单个列表元素。
哪颗行星离太阳最近?Python使用从零开始的索引,所以第一个元素的索引为0。
planets[0]
'Mercury'
下一个离我们最近的行星是什么?
planets[1]
'Venus'
哪颗行星离太阳最远?
列表末尾的元素可以用负数访问,从-1开始:
planets[-1]
'Neptune'
planets[-2]
'Uranus'
Slicing
前三颗行星是什么?我们可以用**slicing(切片)**来回答这个问题:
planets[0:3]
['Mercury', 'Venus', 'Earth']
planets[0:3] 是我们寻找行星元素的方式,从索引0开始,一直到但不包括索引3。
起始和结束索引都是可选的。如果省略起始下标,它就会被假设为0。所以我可以把上面的表达式重写为
planets[:3]
['Mercury', 'Venus', 'Earth']
如果我省略了结束索引,它就会被认为是列表的长度。
planets[3:]
['Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
例如,上面的表达意思是“给我从指标3开始的所有行星”。
切片时也可以使用负下标:
# All the planets except the first and last
planets[1:-1]
['Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus']
# The last 3 planets
planets[-3:]
['Saturn', 'Uranus', 'Neptune']
Changing lists
列表是**“mutable(可变的)”**,这意味着它们可以“适当的”修改。
修改列表的一种方法是给索引或切片表达式赋值。
例如,假设我们想重命名火星:
planets[3] = 'Malacandra'
planets
['Mercury',
'Venus',
'Earth',
'Malacandra',
'Jupiter',
'Saturn',
'Uranus',
'Neptune']
嗯,挺拗口的。让我们通过缩短前3个行星的名字来弥补。
planets[:3] = ['Mur', 'Vee', 'Ur']
print(planets)
# That was silly. Let's give them back their old names
planets[:4] = ['Mercury', 'Venus', 'Earth', 'Mars',]
['Mur', 'Vee', 'Ur', 'Malacandra', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
List functions
Python提供了几个有用的函数来处理列表。
Len
给出了列表的长度:
# How many planets are there?
len(planets)
8
sorted
返回一个排序后的列表:
# The planets sorted in alphabetical order
sorted(planets)
['Earth', 'Jupiter', 'Mars', 'Mercury', 'Neptune', 'Saturn', 'Uranus', 'Venus']
sum
和你预期的一样:
primes = [2, 3, 5, 7]
sum(primes)
17
前面我们使用min
和max
来获取多个参数的最小值或最大值。但我们也可以传入一个列表参数。
max(primes)
7
Interlude: objects
到目前为止,我已经多次使用“object(对象)”这个术语——你可能已经读到Python中的所有东西都是对象。这是什么意思?
简而言之,objects 随身携带一些东西。你可以使用Python的点语法来访问这些东西。
例如,在Python中,数字带有一个名为imag的关联变量,表示数字的虚部。(除非你在做一些非常奇怪的数学运算,否则你可能永远不需要使用它。)
x = 12
# x is a real number, so its imaginary part is 0.
print(x.imag)
# Here's how to make a complex number, in case you've ever been curious:
c = 12 + 3j
print(c.imag)
0
3.0
对象携带的东西也可以包括函数。附加到对象上的函数称为方法。(附加到对象上的非函数的东西,如imag,称为属性。)
例如,数字有一个名为bit_length的方法。同样,我们使用点语法访问它:
x.bit_length
<function int.bit_length()>
要真正调用它,我们需要加上一对括号:
x.bit_length()
4
顺便说一句,如果你做了练习,你实际上已经调用了方法。在练习笔记q1、q2、q3等中,所有对象都有名为check、hint和solution的方法。
就像我们可以将函数传递给help函数一样(例如help(max)),我们也可以传递方法:
help(x.bit_length)
Help on built-in function bit_length:
bit_length() method of builtins.int instance
Number of bits necessary to represent self in binary.
>>> bin(37)
'0b100101'
>>> (37).bit_length()
6
上面的例子完全晦涩难懂。到目前为止,我们所见过的对象类型(数字、函数、布尔值)都没有你可能会用到的属性或方法。
但事实证明,列表有几个你会一直使用的方法。
List methods
list.append
通过在列表末尾添加元素来修改列表:
# Pluto is a planet darn it!
planets.append('Pluto')
为什么上面的单元格没有输出?让我们通过调用help(planets.append)来查看文档。
附注:append是所有list类型对象(不仅仅是planets)都包含的方法,所以我们也可以调用help(list.append)。然而,如果我们试图调用help(append), Python将提示不存在名为”append”的变量。“append”名称只存在于列表中——它不像内置函数max或len那样作为独立名称存在。
help(planets.append)
Help on built-in function append:
append(object, /) method of builtins.list instance
Append object to the end of the list.
阅读文档可以知道list.Append不返回任何东西。但是如果我们检查planets的值,我们可以看到这个方法调用修改了planets的值:
planets
['Mercury',
'Venus',
'Earth',
'Mars',
'Jupiter',
'Saturn',
'Uranus',
'Neptune',
'Pluto']
list.pop
移除并返回列表的最后一个元素:
planets.pop()
'Pluto'
planets
['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
Searching lists
在planets的排列顺序中,Earth落在什么位置?我们可以通过list.index方法获得它的索引。
planets.index('Earth')
2
它排在第三位(即索引为2 - 0的索引!)。
Pluto的索引是什么呢?
planets.index('Pluto')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/tmp/ipykernel_19/2263615293.py in <module>
----> 1 planets.index('Pluto')
ValueError: 'Pluto' is not in list
哦,对了……
为了避免这样的意外,我们可以使用in操作符来确定列表是否包含特定的值:
# Is Earth a planet?
"Earth" in planets
True
# Is Calbefraques a planet?
"Calbefraques" in planets
False
还有一些更有趣的列表方法我们还没有介绍。如果您想了解附加到特定对象上的所有方法和属性,我们可以对对象本身调用help()。例如,help(planets)将告诉我们所有的list方法:
help(planets)
Help on list object:
class list(object)
| list(iterable=(), /)
|
| Built-in mutable sequence.
|
| If no argument is given, the constructor creates a new empty list.
| The argument must be an iterable if specified.
|
| Methods defined here:
|
| __add__(self, value, /)
| Return self+value.
|
| __contains__(self, key, /)
| Return key in self.
|
| __delitem__(self, key, /)
| Delete self[key].
|
| __eq__(self, value, /)
| Return self==value.
|
| __ge__(self, value, /)
| Return self>=value.
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __getitem__(...)
| x.__getitem__(y) <==> x[y]
|
| __gt__(self, value, /)
| Return self>value.
|
| __iadd__(self, value, /)
| Implement self+=value.
|
| __imul__(self, value, /)
| Implement self*=value.
|
| __init__(self, /, *args, **kwargs)
| Initialize self. See help(type(self)) for accurate signature.
|
| __iter__(self, /)
| Implement iter(self).
|
| __le__(self, value, /)
| Return self<=value.
|
| __len__(self, /)
| Return len(self).
|
| __lt__(self, value, /)
| Return self<value.
|
| __mul__(self, value, /)
| Return self*value.
|
| __ne__(self, value, /)
| Return self!=value.
|
| __repr__(self, /)
| Return repr(self).
|
| __reversed__(self, /)
| Return a reverse iterator over the list.
|
| __rmul__(self, value, /)
| Return value*self.
|
| __setitem__(self, key, value, /)
| Set self[key] to value.
|
| __sizeof__(self, /)
| Return the size of the list in memory, in bytes.
|
| append(self, object, /)
| Append object to the end of the list.
|
| clear(self, /)
| Remove all items from list.
|
| copy(self, /)
| Return a shallow copy of the list.
|
| count(self, value, /)
| Return number of occurrences of value.
|
| extend(self, iterable, /)
| Extend list by appending elements from the iterable.
|
| index(self, value, start=0, stop=9223372036854775807, /)
| Return first index of value.
|
| Raises ValueError if the value is not present.
|
| insert(self, index, object, /)
| Insert object before index.
|
| pop(self, index=-1, /)
| Remove and return item at index (default last).
|
| Raises IndexError if list is empty or index is out of range.
|
| remove(self, value, /)
| Remove first occurrence of value.
|
| Raises ValueError if the value is not present.
|
| reverse(self, /)
| Reverse *IN PLACE*.
|
| sort(self, /, *, key=None, reverse=False)
| Stable sort *IN PLACE*.
|
| ----------------------------------------------------------------------
| Static methods defined here:
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __hash__ = None
点击“输出”按钮查看完整的帮助页面。列表有很多方法的名字看起来很奇怪,比如__eq__和__iadd__。现在不要太担心这些。(您可能永远不会直接调用这些方法。但是当我们使用诸如索引或比较运算符之类的语法时,它们会在幕后被调用。)最有趣的方法位于列表的底部(追加、清除、复制等)。
Tuples
元组几乎与列表完全相同。它们只在两个方面有所不同。
1:创建它们的语法使用圆括号而不是方括号
t = (1, 2, 3)
t = 1, 2, 3 # equivalent to above
t
(1, 2, 3)
2:它们不能被修改(它们是不可变的)。
t[0] = 100
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/tmp/ipykernel_19/816329950.py in <module>
----> 1 t[0] = 100
TypeError: 'tuple' object does not support item assignment
元组通常用于具有多个返回值的函数。
例如,float对象的as_integer_ratio()方法以元组的形式返回分子和分母:
x = 0.125
x.as_integer_ratio()
(1, 8)
这些多个返回值可以单独赋值如下:
numerator, denominator = x.as_integer_ratio()
print(numerator / denominator)
0.125
最后,我们深入了解了用于交换两个变量的经典愚蠢Python技巧™!
a = 1
b = 0
a, b = b, a
print(a, b)
0 1
Exercise
Question 1
根据文档字符串完成下面的函数。
def select_second(L):
"""Return the second element of the given list. If the list has no second
element, return None.
"""
pass
return L[1] if len(L) >= 2 else None
# Check your answer
q1.check()
Question 2
你正在分析运动队。每个团队的成员存储在一个列表中。教练是名单上的第一个名字,队长是名单上的第二个名字,其他球员在那之后列出。这些列表存储在另一个列表中,该列表从最好的团队开始,一直到最差的团队。完成下面的功能,选择最差队伍的队长。
def losing_team_captain(teams):
"""Given a list of teams, where each team is a list of names, return the 2nd player (captain)
from the last listed team
"""
return teams[len(teams)-1][1]
pass
# Check your answer
q2.check()
Question 3
下一个迭代的马里奥赛车将有一个特别令人愤怒的新项目,紫色外壳。当使用时,它会将最后一名赛车手扭曲成第一名,并将第一名赛车手扭曲成最后一名。完成下面的函数来实现紫色外壳的效果。
def purple_shell(racers):
"""Given a list of racers, set the first place racer (at the front of the list) to last
place and vice versa.
>>> r = ["Mario", "Bowser", "Luigi"]
>>> purple_shell(r)
>>> r
["Luigi", "Bowser", "Mario"]
"""
pass
racers[0],racers[-1] = racers[-1],racers[0]
# Check your answer
q3.check()
Question 4
以下列表的长度是多少?用您的预测填入可变长度。(尝试对每个列表进行预测,而不只是对其调用len()。)
a = [1, 2, 3]
b = [1, [2, 3]]
c = []
d = [1, 2, 3][1:]
# Put your predictions in the list below. Lengths should contain 4 numbers, the
# first being the length of a, the second being the length of b and so on.
lengths = [3,2,0,2]
# Check your answer
q4.check()
Question 5
我们用列表来记录参加我们聚会的人以及他们到达的顺序。例如,下面的列表代表一个有7位客人的派对,其中Adela第一个出现,Ford最后一个到达:
party_attendees = ['Adela', 'Fleda', 'Owen', 'May', 'Mona', 'Gilbert', 'Ford']
如果一位客人比聚会上至少一半的客人晚到,那么他就被认为是“迟到了”。然而,他们不能是最后一个客人(这太过分了)。在上面的例子中,Mona和Gilbert是唯一迟到的客人。
完成下面的函数,获取聚会参与者和某人的列表,并告诉我们该人是否迟到了。
def fashionably_late(arrivals, name):
"""Given an ordered list of arrivals to the party and a name, return whether the guest with that
name was fashionably late.
"""
pass
return arrivals.index(name) >= len(arrivals) / 2 and arrivals.index(name) != len(arrivals) -1
# Check your answer
q5.check()