2017-06-25 22 views
0

リスト内の文字列を変更しようとしました。私はそれぞれの文字列項目を選択するためのループを設定しているが、私はそれを変更することはできません。私はそれがグローバル/ローカルのスコープの問題か、ミュート可能な/不変の型の問題だと思ったが、私はドキュメントを見てきたが、なぜ私はそのコードを使って文字列を修正できないのか分からないたった今。文字列メソッドを使用してリスト内の文字列を変更しました - 切り捨て

小さなプログラムが完了していないが、アイデアは、私たtableData変数を取り、

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

に見えるようにそれを印刷するためにこれは私が結合し、5時間にしてきた問題であり、そのからさ

# 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

:ここ

https://automatetheboringstuff.com/chapter6/は私のコード(問題は非常に下部にある)されていますで発見のPython第6章実践プロジェクトとボーリングスタッフを自動化

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 

出力:Pythonで

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

、文字列がimmutableをしているあなたは、zipファイルを使用することができます。あなたは

inner_item = inner_item.rjust(colWidths[item]) 

を行うと、あなただけの新しい文字列を作成し、同じラベルはそれを参照作っています。古い値(リストに格納されている)は変更されません。後者だけでなく、より簡潔ですが、またあなたを免除

final_list = [inner_item.rjust(colWidths[item]) 
       for item in tableData for inner_item in 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]) 
いっそ

または、リストの内包表記を使用して、新しいリストを作成:あなたは、インデックスを使用して、リストの要素を変更するか必要があります元のリストをコピーする必要から。

-1

これは、ループを反復している間にループを変更しない理由の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]) 

この1つは動作します:

あなたはまだそれをしたい場合は

が、それはこのようにインデックスを使用してアクセスします。お役に立てれば!

+0

だから、これはループのために項目を変更することがないようにそしてちょうどベストプラクティスですか?私はあなたを正しく理解しているかどうかはわかりません - 私はリストを反復している間にリストを修正していたと思います。私はzip()、map()、リスト内包を教えていなかったので、私はちょっと欲求不満でした。私は機能の開始の近くでリストの理解を使用しましたが、私がそれを見た後でも完全に理解できませんでした –

1

あなたは(あなたが簡単にdeepcopy痛いことを回避することができます)str.rjustであなたのtableDataに文字列を変更する必要はありません。私はあなたが印刷のための書式文字列を適用勧め:

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