python 结构数组_python数据结构学习笔记-3-数组

数组

Python的list、tuple和str是基于数组的序列,list和tuple是存放的对象的引用,str存放的是实际值(an array of characters (not an array of references)),字符在内存中是连续存储的。list、tuple和str都可以通过索引和切片进行操作。模块array可以用于创建存放值的数组,有一个限制是ctype的,不支持自定义的类型。操作方式如:primes = array( 'i' , [2, 3, 5, 7, 11, 13, 17, 19])。

字符串类型在使用时的一个常见的低效的使用方式和优化后的写法。低效的原因是没增加一个 字符就要先生成一个新的字符串实例,然后再连接。改进后的写法先放到列表( list)里,然后再 jion。

# 低效的代码片段

# WARNING: do not do this

letters = '' # start with empty string

for c in document:

if c.isalpha( ):

letters += c # concatenate alphabetic character

# 好的写法

temp = [ ] # start with empty list

for c in document:

if c.isalpha( ): # append alphabetic character

temp.append(c)

letters = ''.join(temp) # compose overall result

#更简洁的写法

letters = ''.join([c for c in document if c.isalpha( )])

letters = ''.join(c for c in document if c.isalpha( ))

动态数组

书上的动态数组的实现代码,简单易懂。

import ctypes

class DynamicArray:

""" A dynamic array class akin to a simplified Python list."""

def __init__(self):

""" Create an empty array."""

self._n = 0 #count actual elements

self._capacity = 1 #default array capacity

self._A = self._make_array(self._capacity) #low-level array

def __len__(self):

"""Return number of elements stored in the array."""

return self._n

def __getitem__(self,k):

"""Return element at index k."""

if not 0 <= k < self._n:

raise IndexError('invalid index')

return self._A[k] #retrieve from array

def append(self, obj):

"""Add object to end of the array."""

if self._n == self._capacity: # not enough room

self._resize(2*self._capacity) #so double capacity

self._A[self._n] = obj

self._n += 1

def _resize(self, c): # nonpublic utitity

"""Resize internal array to capacity c."""

B = self._make_array(c) # new (bigger) array

for k in range(self._n): # for each existing value

B[k] = self._A[k]

self._A = B

self._capacity = c

def _make_array(self, c): # nonpublic utitity

"""Return new array with capacity c."""

return (c * ctypes.py_object)() # see ctypes documentation

if __name__ == '__main__':

da = DynamicArray()

da.append(6)

da.append(2)

for o in da:

print o

列表应用

书上的两个例子。

列表应用一,应用列表(list)实现一个游戏得分的排行榜。类GameEntry记录姓名和得分,类ScoreBoard实现排行榜,它要保证添加新得分时要保证得分是按照顺序排列的,如果空间不够,就要把最后一名挤出去。

class GameEntry:

"""Represents one entry of a list of high scores."""

def __init__(self, name, score):

self._name = name

self._score = score

def get_name(self):

return self_score

def __str__(self):

return '({0}, {1})'.format(self._name, self._score)

class Scoreboard:

"""Fixed-length sequence of high scores in nondecreasing order."""

def __init__(self, capacity=10):

"""Initialize scoreboard with given maximum capacity.

All entries are initially None.

"""

self._board = [None]*capacity #reserve space for future scores

self._n = 0

def __getitem__(self, k):

"""Return entry at index k."""

return self._board[k]

def __str__(self):

"""Return string representation of the high score list."""

return '\n'.join(str(self._board[j]) for j in range(self._n))

def add(self,entry):

"""Consider adding entry to high scores."""

score = entry.get_score()

# Does new entry qualify as a high score?

# answer is yes if board not full or score is higher than last entry

good = self._n < len(self._board) or score > self._board[-1].get_score()

if good:

if self._n < len(self._board): #no score drops form list

self._n += 1 #so overall number increases

# shift lower socres rightward to make room for new entry

j = self._n - 1

while j > 0 and self._board[j-1].get_score() < score:

self._board[j] = self._board[j-1] #shift entry from j-1 to j

j -= 1 #and decrement j

self._board[j] = entry #when done, and new entry

def insertion_sort(A):

"""Sort list of comparable elements into nondecreading order."""

for k in range(1, len(A)): # from 1 to n-1

cur = A[k] # current element to be inserted

j = k # find correct index j for current

while j > 0 and A[j-1] > cur: # element A[j-1] must be after current

A[j] = A[j-1]

j -= 1

A[j] = cur # cur is now in the right place

列表应用二,凯撒密码加密。

class CaesarCipher:

""" Class for doing encryption and decryption using a Caesar cipher. """

def __init__(self, shift):

"""Construct Caesar cipher using given integer shift for rotation."""

encoder = [None] * 26 #temp array for encryption

decoder = [None] * 26 #temp array for decryption

for k in range(26):

encoder[k] = chr((k + shift) % 26 + ord('A'))

decoder[k] = chr((k - shift) % 26 + ord('A'))

self._forward = ''.join(encoder) #will store as string

self._backward = ''.join(decoder) #since fixed

def encrypt(self, message):

"""Return string representing encripted message."""

return self._transform(message, self._forward)

def decrypt(self, secret):

"""Return decrypted message given encrypted secret."""

return self._transform(secret, self._backward)

def _transform(self, original, code):

"""Utility to perform transformation based on given code string."""

msg = list(original)

for k in range(len(msg)):

if msg[k].isupper():

j = ord(msg[k]) - ord('A') # index from 0 to 25

msg[k] = code[j] # replace this character

return ''.join(msg)

if __name__ == '__main__':

cipher = CaesarCipher(3)

message = "THE EAGLE IS IN PLAY; MEET AS JOE'S."

coded = cipher.encrypt(message)

print('Secret: ', coded)

answer = cipher.decrypt(coded)

print('Message: ', answer)

二维数组

在python中二维数组表示为列表中的列表。但是要注意的是初始化时如不小心会犯错。

错误的初始化

In [1]: data = ([0]*2)*3

In [2]: print data

[0, 0, 0, 0, 0, 0]

In [3]: data = [[0]*2]*3

In [4]: data[0][1]=1

In [5]: print data

[[0, 1], [0, 1], [0, 1]]

正确的初始化

In [12]: data = [[0]*2 for j in range(3)]

In [13]: data

Out[13]: [[0, 0], [0, 0], [0, 0]]

In [14]: data[0][1]=1

In [15]: data

Out[15]: [[0, 1], [0, 0], [0, 0]]

二维数组可以用来表示平面上的位置,书上举了一个Tic-Tac-Toe游戏例子。_board是一个3×3的二维数组,记录每个位置放的是'X'、'O'或' '(无棋子); mark表示往[i][j]这个位置上放棋子(做标记), 放棋子时会进行校验;_is_win判断输赢,返回None表示未结束,还可以下。

class TicTacToe:

"""Management of a Tic-Tac-Toe game(does not do strategy)."""

def __init__(self):

"""Start a new game."""

self._board = [[' ']*3 for j in range(3)]

self._player = 'x'

def mark(self, i, j):

"""Put an X or O mark at position (i,j) for next player's turn."""

if not (0 <= i <= 2 and 0 <= j <= 2):

raise ValueError('Invalid board position')

if self._board[i][j] != ' ' :

raise ValueError('Board position occupied')

if self.winner() is not None:

raise ValueError('Game is already complete')

self._board[i][j] = self._player

if self._player == 'X':

self._player = 'O'

else:

self._player = 'X'

def _is_win(self, mark):

"""Check whether the board configuration is a win for the given player."""

board = self._board #local variable for shorthand

return (mark == board[0][0] == board[0][1] == board[0][2] or #row 0

mark == board[1][0] == board[1][1] == board[1][2] or #row 1

mark == board[2][0] == board[2][1] == board[2][2] or #row 2

mark == board[0][0] == board[1][0] == board[2][1] or #column 0

mark == board[0][0] == board[1][1] == board[2][2] or #column 1

mark == board[0][1] == board[1][2] == board[2][2] or #column 2

mark == board[0][0] == board[1][1] == board[2][2] or #diagonal

mark == board[0][2] == board[1][1] == board[2][0] ) #rev diag)

def winner(self):

"""Return mark of winning player, or None to indicate a tie."""

for mark in 'XO':

if self._is_win(mark):

return mark

return None

def __str__(self):

"""Return string representation of current game board."""

rows = ['|'.join(self._board[r]) for r in range(3)]

return '\n-----\n'.join(rows)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值