前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >两天研习Python基础(七) 列表

两天研习Python基础(七) 列表

作者头像
王诗翔呀
发布2020-07-02 15:54:02
7910
发布2020-07-02 15:54:02
举报
文章被收录于专栏:优雅R优雅R

列表变量赋值

  • 简单列表和提取列表元素
代码语言:javascript
复制
>>> vowels = ['a', 'e', 'i', 'o', 'u']
>>> vowels
['a', 'e', 'i', 'o', 'u']
>>> vowels[0]
'a'
>>> vowels[2]
'i'
>>> vowels[10]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

>>> even_numbers = list(range(2, 11, 2))
>>> even_numbers
[2, 4, 6, 8, 10]
>>> even_numbers[-1]
10
>>> even_numbers[-2]
8
>>> even_numbers[-15]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
  • 数据类型混合和多维列表
代码语言:javascript
复制
>>> student = ['learnbyexample', 2016, 'Linux, Vim, Python']
>>> print(student)
['learnbyexample', 2016, 'Linux, Vim, Python']

>>> list_2D = [[1, 3, 2, 10], [1.2, -0.2, 0, 2]]
>>> list_2D[0][0]
1
>>> list_2D[1][0]
1.2
  • Python文档 - 列表[1]

列表切片和修改

  • 类似range()函数,列表索引也是start:stop:stepstop值不被包含在内
  • stackoverflow - 解释切片符号[2]
代码语言:javascript
复制
>>> books = ['Harry Potter', 'Sherlock Holmes', 'To Kill a Mocking Bird']
>>> books[2] = "Ender's Game"
>>> print(books)
['Harry Potter', 'Sherlock Holmes', "Ender's Game"]

>>> prime = [2, 3, 5, 7, 11]
>>> prime[2:4]
[5, 7]
>>> prime[:3]
[2, 3, 5]
>>> prime[3:]
[7, 11]

>>> prime[-1]
11
>>> prime[-1:] # 注意和上一个操作的不同
[11]
>>> prime[-2:]
[7, 11]


>>> prime[::1]
[2, 3, 5, 7, 11]
>>> prime[::2]
[2, 5, 11]
>>> prime[3:1:-1]
[7, 5]
>>> prime[::-1]
[11, 7, 5, 3, 2]
>>> prime[:]
[2, 3, 5, 7, 11]
  • startstop值相同在被程序自动生成时很有用
  • 查看文本处理练习[3]的例子
代码语言:javascript
复制
>>> nums = [1.2, -0.2, 0, 2]
>>> nums[0:0]
[]
>>> nums[2:2]
[]
>>> nums[-1:-1]
[]
>>> nums[21:21]
[]
  • 这种索引格式可以用于抽取列表元素或者修改列表本身
代码语言:javascript
复制
>>> nums = [1.2, -0.2, 0, 2]
>>> nums[:2] = [1]
>>> nums
[1, 0, 2]

>>> nums = [1.2, -0.2, 0, 2, 4, 23]
>>> nums[:5:2] = [1, 4, 3]
>>> nums
[1, -0.2, 4, 2, 3, 23]

>>> nums = [1, 2, 3, 23]
>>> nums[::-1] = [1, 4, 5, 2]
>>> nums
[2, 5, 4, 1]
  • 可以不改变id就修改一个列表,如果变量名在别处使用那么这个操作会非常有用
代码语言:javascript
复制
>>> id(nums)
140598790579336
>>> nums[:] = [1, 2, 5, 4.3]
>>> nums
[1, 2, 5, 4.3]
>>> id(nums)
140598790579336

# 不使用索引[:]则会改变id
>>> nums = [1.2, -0.2, 0, 2]
>>> id(nums)
140598782943752
# 译者注:这应当是另外分配了一个新的地址和变量,然后对当前存在的进行了覆盖

列表拷贝

  • Python中的变量包含对象的引用
  • 例如,当一个整数变量修改后,变量的引用通过一个新的对象进行更新
  • id()[4]函数返回一个对象的“唯一标识符”
  • 对于变量指向不可变的类型(如整型和字符串),这种区分通过不会对它们的使用造成困扰
代码语言:javascript
复制
>>> a = 5
>>> id(a)
10105952
>>> a = 10
>>> id(a)
10106112

>>> b = a
>>> id(b)
10106112
>>> b = 4
>>> b
4
>>> a
10
>>> id(b)
10105920
  • 但是对于指向可变类型(比如列表)的变量,知道变量是如何拷贝和传入函数是非常重要的
  • 当列表中的一个元素被修改,它是通过改变对象那个索引的值实现的
代码语言:javascript
复制
>>> a = [1, 2, 5, 4.3]
>>> a
[1, 2, 5, 4.3]
>>> b = a
>>> b
[1, 2, 5, 4.3]
>>> id(a)
140684757120264
>>> id(b)
140684757120264
>>> b[0] = 'xyz'
>>> b
['xyz', 2, 5, 4.3]
>>> a
['xyz', 2, 5, 4.3]
  • 避免通过索引的方式拷贝列表,它对1维列表起作用,但不适用于更高维度
代码语言:javascript
复制
>>> prime = [2, 3, 5, 7, 11]
>>> b = prime[:]
>>> id(prime)
140684818101064
>>> id(b)
140684818886024
>>> b[0] = 'a'
>>> b
['a', 3, 5, 7, 11]
>>> prime
[2, 3, 5, 7, 11]

>>> list_2D = [[1, 3, 2, 10], [1.2, -0.2, 0, 2]]
>>> a = list_2D[:]
>>> id(list_2D)
140684818102344
>>> id(a)
140684818103048
>>> a
[[1, 3, 2, 10], [1.2, -0.2, 0, 2]]
>>> a[0][0] = 'a'
>>> a
[['a', 3, 2, 10], [1.2, -0.2, 0, 2]]
>>> list_2D
[['a', 3, 2, 10], [1.2, -0.2, 0, 2]]
  • 使用copy[5]模块替换
代码语言:javascript
复制
>>> import copy
>>> list_2D = [[1, 3, 2, 10], [1.2, -0.2, 0, 2]]
>>> c = copy.deepcopy(list_2D)
>>> c[0][0] = 'a'
>>> c
[['a', 3, 2, 10], [1.2, -0.2, 0, 2]]
>>> list_2D
[[1, 3, 2, 10], [1.2, -0.2, 0, 2]]

列表方法和混杂

  • 添加元素到列表
代码语言:javascript
复制
>>> books = []
>>> books
[]
>>> books.append('Harry Potter')
>>> books
['Harry Potter']

>>> even_numbers
[2, 4, 6, 8, 10]
>>> even_numbers += [12, 14, 16, 18, 20]
>>> even_numbers
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

>>> even_numbers = [2, 4, 6, 8, 10]
>>> even_numbers.extend([12, 14, 16, 18, 20])
>>> even_numbers
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

>>> a = [[1, 3], [2, 4]]
>>> a.extend([[5, 6]])
>>> a
[[1, 3], [2, 4], [5, 6]]
  • 从列表中删除元素 - 基于索引
代码语言:javascript
复制
>>> prime = [2, 3, 5, 7, 11]
>>> prime.pop()
11
>>> prime
[2, 3, 5, 7]
>>> prime.pop(0)
2
>>> prime
[3, 5, 7]

>>> list_2D = [[1, 3, 2, 10], [1.2, -0.2, 0, 2]]
>>> list_2D[0].pop(0)
1
>>> list_2D
[[3, 2, 10], [1.2, -0.2, 0, 2]]

>>> list_2D.pop(1)
[1.2, -0.2, 0, 2]
>>> list_2D
[[3, 2, 10]]
  • 使用del[6]删除元素
代码语言:javascript
复制
>>> nums = [1.2, -0.2, 0, 2, 4, 23]
>>> del nums[1]
>>> nums
[1.2, 0, 2, 4, 23]
# 也可以使用切片
>>> del nums[1:4]
>>> nums
[1.2, 23]

>>> list_2D = [[1, 3, 2, 10], [1.2, -0.2, 0, 2]]
>>> del list_2D[0][1]
>>> list_2D
[[1, 2, 10], [1.2, -0.2, 0, 2]]

>>> del list_2D[0]
>>> list_2D
[[1.2, -0.2, 0, 2]]
  • 清洗列表
代码语言:javascript
复制
>>> prime = [2, 3, 5, 7, 11]
>>> prime.clear()
>>> prime
[]
  • 从列表中删除元素 - 基于值
代码语言:javascript
复制
>>> even_numbers = [2, 4, 6, 8, 10]
>>> even_numbers.remove(8)
>>> even_numbers
[2, 4, 6, 10]
>>> even_numbers.remove(12)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list
  • 在特定的索引位置插入元素
代码语言:javascript
复制
>>> books = ['Harry Potter', 'Sherlock Holmes', 'To Kill a Mocking Bird']
>>> books.insert(2, "The Martian")
>>> books
['Harry Potter', 'Sherlock Holmes', 'The Martian', 'To Kill a Mocking Bird']
  • 获取元素的索引
代码语言:javascript
复制
>>> even_numbers = [2, 4, 6, 8, 10]
>>> even_numbers.index(6)
2
>>> even_numbers.index(12)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 12 is not in list
  • 查看元素是否存在
代码语言:javascript
复制
>>> prime = [2, 3, 5, 7, 11]
>>> 3 in prime
True
>>> 13 in prime
False
  • 排序[7]
代码语言:javascript
复制
>>> a = [1, 5.3, 321, 0, 1, 2]
>>> a.sort()
>>> a
[0, 1, 1, 2, 5.3, 321]

>>> a = [1, 5.3, 321, 0, 1, 2]
>>> a.sort(reverse=True)
>>> a
[321, 5.3, 2, 1, 1, 0]

基于键key[8]进行排序,例如基于字符串长度lambda表达式[9]在比如传递自定义单个表达式、基于第二个字母进行排序中很有用

代码语言:javascript
复制
>>> words = ['fuliginous', 'crusado', 'morello', 'irk', 'seam']
>>> words.sort(key=len)
>>> words
['irk', 'seam', 'crusado', 'morello', 'fuliginous']

>>> words.sort(key=lambda x: x[1])
>>> words
['seam', 'morello', 'irk', 'crusado', 'fuliginous']

如果不想要改变原始列表,使用sorted[10]函数

代码语言:javascript
复制
>>> nums = [-1, 34, 0.2, -4, 309]
>>> nums_desc = sorted(nums, reverse=True)
>>> nums_desc
[309, 34, 0.2, -1, -4]

>>> sorted(nums, key=abs)
[0.2, -1, -4, 34, 309]
  • minmax
代码语言:javascript
复制
>>> a = [321, 899.232, 5.3, 2, 1, -1]
>>> min(a)
-1
>>> max(a)
899.232
  • 元素存在的次数(数目)
代码语言:javascript
复制
>>> nums = [15, 99, 19, 382, 43, 19]
>>> nums.count(99)
1
>>> nums.count(19)
2
>>> nums.count(23)
0
  • 按位置翻转列表
代码语言:javascript
复制
>>> prime = [2, 3, 5, 7, 11]
>>> id(prime)
140684818102088
>>> prime.reverse()
>>> prime
[11, 7, 5, 3, 2]
>>> id(prime)
140684818102088

>>> a = [1, 5.3, 321, 0, 1, 2]
>>> id(a)
140684818886024
>>> a = a[::-1]
>>> a
[2, 1, 0, 321, 5.3, 1]
>>> id(a)
140684818102664
  • len[11]函数获取列表的大小
代码语言:javascript
复制
>>> prime
[2, 3, 5, 7, 11]
>>> len(prime)
5

>>> s = len(prime) // 2
>>> prime[:s]
[2, 3]
>>> prime[s:]
[5, 7, 11]
  • 数值列表求和
代码语言:javascript
复制
>>> a
[321, 5.3, 2, 1, 1, 0]
>>> sum(a)
330.3
  • all[12]any[13]函数
代码语言:javascript
复制
>>> conditions = [True, False, True]
>>> all(conditions)
False
>>> any(conditions)
True

>>> conditions[1] = True
>>> all(conditions)
True

>>> a = [321, 5.3, 2, 1, 1, 0]
>>> all(a)
False
>>> any(a)
True
  • 比较列表
代码语言:javascript
复制
>>> prime
[2, 3, 5, 7, 11]
>>> a = [4, 2]
>>> prime == a
False

>>> prime == [2, 3, 5, 11, 7]
False
>>> prime == [2, 3, 5, 7, 11]
True

进一步阅读

  • Python文档 - 列表详情[14]
  • Python文档 - 集合[15]

循环

代码语言:javascript
复制
#!/usr/bin/python3

numbers = [2, 12, 3, 25, 624, 21, 5, 9, 12]
odd_numbers  = []
even_numbers = []

for num in numbers:
    odd_numbers.append(num) if(num % 2) else even_numbers.append(num)

print("numbers:      {}".format(numbers))
print("odd_numbers:  {}".format(odd_numbers))
print("even_numbers: {}".format(even_numbers))
  • 基本上不需要元素索引也足以处理列表的每一个元素
代码语言:javascript
复制
$ ./list_looping.py
numbers:      [2, 12, 3, 25, 624, 21, 5, 9, 12]
odd_numbers:  [3, 25, 21, 5, 9]
even_numbers: [2, 12, 624, 12]
  • 如果同时需要索引和元素,使用enumerate()函数
代码语言:javascript
复制
#!/usr/bin/python3

north_dishes = ['Aloo tikki', 'Baati', 'Khichdi', 'Makki roti', 'Poha']

print("My favorite North Indian dishes:")
for idx, item in enumerate(north_dishes):
    print("{}. {}".format(idx + 1, item))
  • 在这个例子中,我们获取了包含每一次迭代元素和索引(从0开始)的元组[16]
  • Python文档 - enumerate[17]
代码语言:javascript
复制
$ ./list_looping_enumeration.py
My favorite North Indian dishes:
1. Aloo tikki
2. Baati
3. Khichdi
4. Makki roti
5. Poha
  • 也可以指定一个start值
代码语言:javascript
复制
>>> north_dishes = ['Aloo tikki', 'Baati', 'Khichdi', 'Makki roti', 'Poha']
>>> for idx, item in enumerate(north_dishes, start=1):
...     print(idx, item, sep='. ')
...
1. Aloo tikki
2. Baati
3. Khichdi
4. Makki roti
5. Poha
  • 使用zip()同时迭代两者及以上的列表
  • Python文档 - zip[18]
代码语言:javascript
复制
>>> odd = [1, 3, 5]
>>> even = [2, 4, 6]
>>> for i, j in zip(odd, even):
...     print(i + j)
...
3
7
11

列表推导式

代码语言:javascript
复制
#!/usr/bin/python3

import time

numbers = list(range(1,100001))
fl_square_numbers = []

# 引用时间
t0 = time.perf_counter()

# ------------ for 循环 ------------
for num in numbers:
    fl_square_numbers.append(num * num)

# 引用时间
t1 = time.perf_counter()

# ------- 列表推导式 -------
lc_square_numbers = [num * num for num in numbers]

# 执行结果
t2 = time.perf_counter()
fl_time = t1 - t0
lc_time = t2 - t1
improvement = (fl_time - lc_time) / fl_time * 100

print("Time with for loop:           {:.4f}".format(fl_time))
print("Time with list comprehension: {:.4f}".format(lc_time))
print("Improvement:                  {:.2f}%".format(improvement))

if fl_square_numbers == lc_square_numbers:
    print("\nfl_square_numbers and lc_square_numbers are equivalent")
else:
    print("\nfl_square_numbers and lc_square_numbers are NOT equivalent")
  • 列表推导式是一些通用循环结构的一种Python化方式
  • 通常比循环更易读和省时间
  • 这个例子中,在列表推导式中没有调用append()方法也能节省大量的时间
  • 这个例子中的时间值是相对的差值
    • 一般用于比较两次运行语句的时间差异,与机器无关
代码语言:javascript
复制
$ ./list_comprehension.py
Time with for loop:           0.0142
Time with list comprehension: 0.0062
Improvement:                  56.36%

fl_square_numbers and lc_square_numbers are equivalent
  • 条件列表推导式
代码语言:javascript
复制
# 使用在列表推导式中使用if-else条件语句
numbers = [2, 12, 3, 25, 624, 21, 5, 9, 12]
odd_numbers  = []
even_numbers = []
[odd_numbers.append(num) if(num % 2) else even_numbers.append(num) for num in numbers]

# 或者一种更简单和易读的方式
numbers = [2, 12, 3, 25, 624, 21, 5, 9, 12]
odd_numbers  = [num for num in numbers if num % 2]
even_numbers = [num for num in numbers if not num % 2]
  • zip示例
代码语言:javascript
复制
>>> p = [1, 3, 5]
>>> q = [3, 214, 53]
>>> [i+j for i,j in zip(p, q)]
[4, 217, 58]
>>> [i*j for i,j in zip(p, q)]
[3, 642, 265]

如果序列需要传入另一个函数,使用生成器表达式[19]

代码语言:javascript
复制
>>> sum(i*j for i,j in zip(p, q))
910

进一步阅读

更多例子,包括嵌套循环,查看这些:

  • Python文档 - 列表推导式[20]
  • Python列表推导式:可视化解释[21]
  • 列表推导式和功能性函数比for循环快吗?[22]
  • Python文档 - perf_counter[23]
    • 理解perf_counter和process_time[24]
  • Python文档 - timeit[25]

获取列表作为用户输入

代码语言:javascript
复制
>>> b = input('Enter strings separated by space: ').split()
Enter strings separated by space: foo bar baz
>>> b
['foo', 'bar', 'baz']

>>> nums = [int(n) for n in input('Enter numbers separated by space: ').split()]
Enter numbers separated by space: 1 23 5
>>> nums
[1, 23, 5]

>>> ip_str = input('Enter prime numbers separated by comma: ')
Enter prime numbers separated by comma: 3,5,7
>>> primes = [int(n) for n in ip_str.split(',')]
>>> primes
[3, 5, 7]
  • 因为用户输入都会被当做字符串,需要基于共同的分隔符和所需要的数据类型进行处理

从列表中获取随机元素

  • 获取一个随机元素
代码语言:javascript
复制
>>> import random
>>> a = [4, 5, 2, 76]
>>> random.choice(a)
76
>>> random.choice(a)
4
  • 随机重排列表元素
代码语言:javascript
复制
>>> random.shuffle(a)
>>> a
[5, 2, 76, 4]
  • 获取列表的随机切片,不修改列表变量
代码语言:javascript
复制
>>> random.sample(a, k=3)
[76, 2, 5]

>>> random.sample(range(1000), k=5)
[68, 203, 15, 757, 580]
  • 使用Python文档 - iter[26]创建一个迭代变量从列表中获取无重复的随机元素
  • 它与简单使用洗牌后的列表的区别在于,可以避免需要维护独立的索引计数器和当索引超界时自动引发的异常
代码语言:javascript
复制
>>> nums = [1, 3, 6, -12, 1.2, 3.14]
>>> random.shuffle(nums)
>>> nums_iter = iter(nums)
>>> print(next(nums_iter))
3.14
>>> print(next(nums_iter))
1.2
>>> for n in nums_iter:
...     print(n)
...
1
3
-12
6
>>> print(next(nums_iter))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
  • Python文档 - random[27]获取更多信息
    • 3.6版本更新 - random.choices[28]
  • Python文档 - next[29]
  • 另见yield[30]

参考资料

[1]Python文档 - 列表: https://docs.python.org/3/tutorial/introduction.html#lists

[2]stackoverflow - 解释切片符号: https://stackoverflow.com/questions/509211/explain-pythons-slice-notation

[3]文本处理练习: ./Exercises.md#text-processing

[4]id(): https://docs.python.org/3/library/functions.html#id

[5]copy: https://docs.python.org/3/library/copy.html#module-copy

[6]del: https://docs.python.org/3/reference/simple_stmts.html#del

[7]排序: https://docs.python.org/3/library/stdtypes.html#list.sort

[8]基于键key: https://docs.python.org/3/howto/sorting.html#sortinghowto

[9]lambda表达式: https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions

[10]sorted: https://docs.python.org/3/library/functions.html#sorted

[11]len: https://docs.python.org/3/library/functions.html#len

[12]all: https://docs.python.org/3/library/functions.html#all

[13]any: https://docs.python.org/3/library/functions.html#any

[14]Python文档 - 列表详情: https://docs.python.org/3/tutorial/datastructures.html#more-on-lists

[15]Python文档 - 集合: https://docs.python.org/3/library/collections.html

[16]元组: ./Sequence_Set_Dict_data_types.md#tuples

[17]Python文档 - enumerate: https://docs.python.org/3/library/functions.html#enumerate

[18]Python文档 - zip: https://docs.python.org/3/library/functions.html#zip

[19]生成器表达式: https://docs.python.org/3/tutorial/classes.html#generator-expressions

[20]Python文档 - 列表推导式: https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions

[21]Python列表推导式:可视化解释: http://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/

[22]列表推导式和功能性函数比for循环快吗?: http://stackoverflow.com/questions/22108488/are-list-comprehensions-and-functional-functions-faster-than-for-loops

[23]Python文档 - perf_counter: https://docs.python.org/3/library/time.html#time.perf_counter

[24]理解perf_counter和process_time: http://stackoverflow.com/questions/25785243/understanding-time-perf-counter-and-time-process-time

[25]Python文档 - timeit: https://docs.python.org/3/library/timeit.html

[26]Python文档 - iter: https://docs.python.org/3/library/functions.html#iter

[27]Python文档 - random: https://docs.python.org/3/library/random.html

[28]random.choices: https://docs.python.org/3/library/random.html#random.choices

[29]Python文档 - next: https://docs.python.org/3/library/functions.html#next

[30]yield: https://stackoverflow.com/questions/231767/what-is-the-function-of-the-yield-keyword

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

本文分享自 优雅R 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 列表变量赋值
  • 列表切片和修改
  • 列表拷贝
  • 列表方法和混杂
  • 循环
  • 列表推导式
  • 获取列表作为用户输入
  • 从列表中获取随机元素
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档