【python基础】7-列表

作者: 王诗翔 | 来源:发表于2018-02-25 00:12 被阅读26次

    列表变量赋值

    • 简单列表和提取列表元素
    >>> 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
    
    • 数据类型混合和多维列表
    >>> 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
    

    列表切片和修改

    >>> 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值相同在被程序自动生成时很有用
    • 查看文本处理练习的例子
    >>> nums = [1.2, -0.2, 0, 2]
    >>> nums[0:0]
    []
    >>> nums[2:2]
    []
    >>> nums[-1:-1]
    []
    >>> nums[21:21]
    []
    
    • 这种索引格式可以用于抽取列表元素或者修改列表本身
    >>> 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就修改一个列表,如果变量名在别处使用那么这个操作会非常有用
    >>> 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()函数返回一个对象的“唯一标识符”
    • 对于变量指向不可变的类型(如整型和字符串),这种区分通过不会对它们的使用造成困扰
    >>> a = 5
    >>> id(a)
    10105952
    >>> a = 10
    >>> id(a)
    10106112
    
    >>> b = a
    >>> id(b)
    10106112
    >>> b = 4
    >>> b
    4
    >>> a
    10
    >>> id(b)
    10105920
    
    • 但是对于指向可变类型(比如列表)的变量,知道变量是如何拷贝和传入函数是非常重要的
    • 当列表中的一个元素被修改,它是通过改变对象那个索引的值实现的
    >>> 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维列表起作用,但不适用于更高维度
    >>> 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模块替换
    >>> 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]]
    

    列表方法和混杂

    • 添加元素到列表
    >>> 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]]
    
    • 从列表中删除元素 - 基于索引
    >>> 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删除元素
    >>> 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]]
    
    • 清洗列表
    >>> prime = [2, 3, 5, 7, 11]
    >>> prime.clear()
    >>> prime
    []
    
    • 从列表中删除元素 - 基于值
    >>> 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
    
    • 在特定的索引位置插入元素
    >>> 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']
    
    • 获取元素的索引
    >>> 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
    
    • 查看元素是否存在
    >>> prime = [2, 3, 5, 7, 11]
    >>> 3 in prime
    True
    >>> 13 in prime
    False
    
    >>> 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进行排序,例如基于字符串长度
    lambda表达式在比如传递自定义单个表达式、基于第二个字母进行排序中很有用

    >>> 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函数

    >>> 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
    >>> a = [321, 899.232, 5.3, 2, 1, -1]
    >>> min(a)
    -1
    >>> max(a)
    899.232
    
    • 元素存在的次数(数目)
    >>> nums = [15, 99, 19, 382, 43, 19]
    >>> nums.count(99)
    1
    >>> nums.count(19)
    2
    >>> nums.count(23)
    0
    
    • 按位置翻转列表
    >>> 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函数获取列表的大小
    >>> prime
    [2, 3, 5, 7, 11]
    >>> len(prime)
    5
    
    >>> s = len(prime) // 2
    >>> prime[:s]
    [2, 3]
    >>> prime[s:]
    [5, 7, 11]
    
    • 数值列表求和
    >>> a
    [321, 5.3, 2, 1, 1, 0]
    >>> sum(a)
    330.3
    
    >>> 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
    
    • 比较列表
    >>> 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
    

    进一步阅读

    循环

    #!/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))
    
    • 基本上不需要元素索引也足以处理列表的每一个元素
    $ ./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()函数
    #!/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))
    
    $ ./list_looping_enumeration.py
    My favorite North Indian dishes:
    1. Aloo tikki
    2. Baati
    3. Khichdi
    4. Makki roti
    5. Poha
    
    • 也可以指定一个start值
    >>> 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
    
    >>> odd = [1, 3, 5]
    >>> even = [2, 4, 6]
    >>> for i, j in zip(odd, even):
    ...     print(i + j)
    ...
    3
    7
    11
    

    列表推导式

    #!/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()方法也能节省大量的时间
    • 这个例子中的时间值是相对的差值
      • 一般用于比较两次运行语句的时间差异,与机器无关
    $ ./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
    
    • 条件列表推导式
    # 使用在列表推导式中使用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示例
    >>> 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]
    

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

    >>> sum(i*j for i,j in zip(p, q))
    910
    

    进一步阅读

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

    获取列表作为用户输入

    >>> 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]
    
    • 因为用户输入都会被当做字符串,需要基于共同的分隔符和所需要的数据类型进行处理

    从列表中获取随机元素

    • 获取一个随机元素
    >>> import random
    >>> a = [4, 5, 2, 76]
    >>> random.choice(a)
    76
    >>> random.choice(a)
    4
    
    • 随机重排列表元素
    >>> random.shuffle(a)
    >>> a
    [5, 2, 76, 4]
    
    • 获取列表的随机切片,不修改列表变量
    >>> random.sample(a, k=3)
    [76, 2, 5]
    
    >>> random.sample(range(1000), k=5)
    [68, 203, 15, 757, 580]
    
    • 使用Python文档 - iter创建一个迭代变量从列表中获取无重复的随机元素
    • 它与简单使用洗牌后的列表的区别在于,可以避免需要维护独立的索引计数器和当索引超界时自动引发的异常
    >>> 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基础】7-列表

        本文链接:https://www.haomeiwen.com/subject/zshhxftx.html