zoukankan      html  css  js  c++  java
  • Python如何快速复制序列?

    1 基本用法

    把序列乘以一个整数,就会产生一个新序列。这个新序列是原始序列复制了整数份,然后再拼接起来的结果。

    l=[1,2,3]
    l2=l * 3
    logging.info('l2 -> %s',l2)
    l3=5 * 'deniro'
    logging.info('l3 -> %s',l3)
    复制代码

    运行结果:

    INFO - l2 -> [1, 2, 3, 1, 2, 3, 1, 2, 3]
    INFO - l3 -> denirodenirodenirodenirodeniro
    复制代码

    * 复制语法不会修改原有的操作对象,而是构建出一个全新的序列。

    2 列表陷阱

    a * n 语法中,a 为列表,n 为需要复制的列表数。如果 a 列表中的元素是基本类型的话,没什么问题。但如果 a 列表中的元素是对象的引用的话,那么这些复制出来的列表中的引用其实指向的是同一个引用。

    Luciano Ramalho 举了一个井字棋示例。

    井字棋,英文名叫Tic-Tac-Toe,是一种在3*3格子上进行的连珠游戏,和五子棋类似,由于棋盘一般不画边框,格线排成井字故得名。游戏需要的工具仅为纸和笔,然后由分别代表O和X的两个游戏者轮流在格子里留下标记(一般来说先手者为X),任意三个标记形成一条直线,则为获胜。

    (1)错误示例 1

    weird_board = [['_'] * 3] * 3
    logging.info('weird_board -> %s', weird_board)
    weird_board[1][2] = 'X'
    logging.info('weird_board -> %s', weird_board)
    复制代码

    运行结果:

    INFO - weird_board -> [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
    INFO - weird_board -> [['_', '_', 'X'], ['_', '_', 'X'], ['_', '_', 'X']]
    复制代码

    可以看到虽然代码中只修改了 [1][2] 位置的值,但却影响到了三处地方。这就说明这三处其实指向的是同一个引用。

    (2)错误示例 2

    这个示例犯的错与前一个示例相同,都是把同一个对象追加到同一块游戏板中(board)。

    row = ['_'] * 3
    board = []
    for i in range(3):
        board.append(row)
    logging.info('board -> %s', board)
    board[1][2] = 'X'
    logging.info('board -> %s', board)
    复制代码

    运行结果:

    INFO - board -> [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
    INFO - board -> [['_', '_', 'X'], ['_', '_', 'X'], ['_', '_', 'X']]
    复制代码

    (3)正确示例

    对示例 2 进行改造,就可以避免上述问题。

    board = []
    for i in range(3):
        row = ['_'] * 3
        board.append(row)
    logging.info('board -> %s', board)
    board[1][2] = 'X'
    logging.info('board -> %s', board)
    复制代码

    运行结果:

    INFO - board -> [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
    INFO - board -> [['_', '_', '_'], ['_', '_', 'X'], ['_', '_', '_']]
    复制代码

    这里把 row = ['_'] * 3 放入 for 循环中,这样每一次循环都会新建一个 row,然后再放入游戏板中。这样游戏板中的每一个单元格都是独立的,互不影响。

    利用列表推导方法,还可以简化示例代码:

    board = [['_'] * 3 for i in range(3)]
    logging.info('board -> %s', board)
    
    board[1][2] = 'X'
    logging.info('board -> %s', board)
  • 相关阅读:
    0149-函数可以做参数.abb
    0139-文件操作之二进制方式打开模式(一).abb
    0138-文件操作之基本打开模式.abb
    0130-实例之python实现随机验证码.abb
    0127-python内置函数(一).abb
    0126-lambda表达式.abb
    0113-全局变量和局部变量.abb
    函数的动态参数
    0103-深浅拷贝.abb
    0102-不同数据类型在内存中的存址方式
  • 原文地址:https://www.cnblogs.com/lyck/p/13625037.html
Copyright © 2011-2022 走看看