为字符的矩形矩阵添加边框(*)

时间:2018-08-09 05:08:19

标签: python python-3.x

我正在尝试添加*作为矩形字符矩阵的边框。例如,

["abc", "ded"]

应该返回

["*****","*abc*","*ded*","*****"]

我要做的是创建一个新的矩阵,其中的行和列比原始矩阵多2列,并用*填充。所以问题是当我用原始字母替换*内部时,出现索引不足的错误。我不知道为什么吗?

def addBorder(picture):
  m=len(picture) #number of rows
  n=len(picture[0]) #num of columns
  newpic=[['*'*(n+2)]for y in range(m+2)] 
  for x in range(1,m+1):
    for y in range(1,n+1):
     newpic[x][y]=picture[x-1][y-1]
  return newpic  

3 个答案:

答案 0 :(得分:4)

字符串是不可变的,因此您不能通过索引将它们内的单个字符“编辑”,这就是您在for x ..: for y: ...循环中要尝试的操作。

要保留大部分代码,可以将其更改为:

def addBorder(picture):
  m=len(picture) #number of rows
  n=len(picture[0]) #num of columns
  newpic=[['*'*(n+2)]for y in range(m+2)] 

  for idx,text in enumerate(picture): # get text and index here
     newpic[idx+1] = '*' + text+ '*'  # change text in +1 row in target list
  return newpic 

print(addBorder( ["abc", "ded"]))

输出:

[['*****'], '*abc*', '*ded*', ['*****']]

更改更多代码:

def addBorder(picture):
    # slightly more compley length computation, will work for ragged text as well
    maxL = max(len(x) for x in picture) 
    patt = "*{:<"+str(maxL)+"}*"   # left justified by maxL , see link below
    rv = []
    rv.append('*'*(maxL+2))    # top border

    for t in picture:
        rv.append(patt.format(t)) # text + adornment

    rv.append('*'*(maxL+2))    # bottom border

    return rv

print(addBorder( ["abc", "defgh","i"]))

输出:

['*******', 
 '*abc  *', 
 '*defgh*', 
 '*i    *', 
 '*******']

链接:string format mini language


您的索引不足错误消息在某种程度上具有误导性-您在列表的范围之内,但是您正在尝试操纵字符串-我以为'str' object does not support item assignment在这里会更合适。 ..

编辑:请参阅Azats answer,了解为什么会发生您的错误-我留了文字,这样他的帖子就不会丢失其引用。

debugging your code

答案 1 :(得分:2)

如果我理解正确,您正在尝试

  1. 使用* newpic填充。
  2. 修改newpic[1:-1]并用picture元素内容替换*(不包括边框)。

这种方法存在str对象不可变性的问题,但是即使它们是可变的,这似乎也无法创建** ... **字符串,然后逐个字符地对其进行突变。

关于您的错误:正如@PatrickArtner所说的那样,它不会引起误解,它源自错字(我想),因为您正在创建listlist的{​​{1}} :

str

因此,当>>> m = 3 >>> n = 4 >>> [['*'*(n+2)]for y in range(m+2)] [['******'], ['******'], ['******'], ['******'], ['******']] 等于y时,您会收到此错误消息(因为每个1子列表中只有一个newpic元素)。

我们可以尝试创建str并将list附加到其中,而不用尝试修改str中的list

str

测试

def addBorder(picture,
              border_size=1):
    max_substring_length = max(map(len, picture))
    # top border
    result = ['*' * (max_substring_length + border_size * 2)]
    for substring in picture:
        diff = max_substring_length - len(substring)
        additional_length, extra = divmod(diff, 2)
        # handling non-equivalent case
        prepend = '*' * (border_size + additional_length + extra)
        append = '*' * (border_size + additional_length)
        result.append(prepend + substring + append)
    # bottom border
    result.append('*' * (max_substring_length + border_size * 2))
    return result

给我们

for string in addBorder(["abc", "ded"]):
    print(string)

大小写不相等

*****
*abc*
*ded*
*****

给我们

for string in addBorder(["abc", "deed"]):
    print(string)

答案 2 :(得分:0)

在C ++中

  std::vector<std::string> addBorder(std::vector<std::string> picture) 
  {
  for(auto &p: picture)
     p = "*"+p+"*";
  picture.insert(picture.begin(), string(picture[0].size(),'*'));
  picture.insert(picture.end(), string(picture[0].size(),'*'));
  return picture;
  }