我在尝试修改列表中的字符串时遇到问题。我有一个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()
答案 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])
这个会奏效。希望这有帮助!