使用字符串方法修改列表中的字符串 - 难倒

时间:2017-06-25 20:42:38

标签: python list function

我在尝试修改列表中的字符串时遇到问题。我有一个for循环设置来选择每个字符串项,但我无法修改它。我认为它可能是一个全局/本地范围问题或一个muteable / immutable类型问题,但我查看了文档,我无法找出为什么我不能用我现有的代码修改字符串马上。

小程序不完整,但我的想法是获取我的tableData变量并将其打印为

  apples Alice  dogs
 oranges   Bob  cats
cherries Carol moose
  banana David goose

这是一个我已经合并了5个小时的问题,它来自Automate the Boring Stuff with Python第6章练习项目:https://automatetheboringstuff.com/chapter6/

这是我的代码(问题在最底层):

# This program will take a list of string lists and print a table of the strings.

from copy import deepcopy
tableData = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose']]


def print_table():
'''This function will take any list of lists and print it in a table format
with evenly spaced columns.'''
    # First I wanted to identify the max length of my columns without making changes to my original list
    copied_list = deepcopy(tableData)  
    for copied_innerlist in range(len(copied_list)):
        copied_list[copied_innerlist].sort(key=len, reverse=True)  # sort each inner list by length
    colWidths = [len(copied_innerlist[0]) for copied_innerlist in copied_list]  # change the column width variable to reflect the length of longest string in each inner list

    # Now that I've stored my columns widths I want to apply them to all the strings without affecting the original
    final_list = deepcopy(tuple(tableData))

    for item in range(len(final_list)):
        for inner_item in final_list[item]:
            inner_item = inner_item.rjust(colWidths[item])
            '''WHY WONT THIS RJUST METHOD STICK '''


    print(final_list)
    """this just looks like that original list! :( """

print_table()

4 个答案:

答案 0 :(得分:2)

在Python中,字符串是immutable。当你这样做

inner_item = inner_item.rjust(colWidths[item])

您只是创建新字符串并使相同的标签引用它。旧值(存储在列表中)保持不变。您需要使用索引修改列表元素:

for i in range(len(final_list)):
    for j in range(len(final_list[i])):
        final_list[i][j] = final_list[i][j].rjust(colWidths[i])

或者,更好的是,使用列表解析构建新列表:

final_list = [inner_item.rjust(colWidths[item])
              for item in tableData for inner_item in item]

后者不仅更简洁,而且还免除了复制原始列表的需要。

答案 1 :(得分:1)

您不需要使用tableData修改str.rjust中的字符串(您可以轻松避免痛苦 deepcopy)。我建议你应用字符串格式进行打印:

tableData = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose']]

def print_table(data):
    lens = [max(map(len, x)) for x in data]  # get max length per column        
    lst = zip(*data)                         # transpose table
    for x in lst:
        print("{:>{l[0]}} {:>{l[1]}} {:>{l[2]}}".format(*x, l=lens))

print_table(tableData)
  apples Alice  dogs
 oranges   Bob  cats
cherries Carol moose
  banana David goose

答案 2 :(得分:0)

您可以使用zip:

tableData = [['apples', 'oranges', 'cherries', 'banana'],
         ['Alice', 'Bob', 'Carol', 'David'],
         ['dogs', 'cats', 'moose', 'goose']]


new = list(map(list, zip(*tableData)))

for i in new:
    print i

输出:

['apples', 'Alice', 'dogs']
['oranges', 'Bob', 'cats']
['cherries', 'Carol', 'moose']
['banana', 'David', 'goose']

答案 3 :(得分:-1)

这是您在迭代循环时不修改循环的原因之一。如果您尝试同时更改和计算循环内的可迭代内容,可能会导致问题here

  

永远不要改变你正在循环的容器,因为那个容器上的迭代器不会被告知你的改动,正如你所注意到的那样,很可能产生一个非常不同的循环和/或一个不正确的循环

如果您仍想这样做,请使用以下索引访问它:

for item in range(len(final_list)):
        for index,inner_item in enumerate(final_list[item]):
            final_list[item][index] = inner_item.rjust(colWidths[item])

这个会奏效。希望这有帮助!