python自己学習日記9-データ構造の選択


1.プログラムを作成し、ファイルから単語のリストを読み込み、返信されたすべての単語のセットを印刷する
今回の回文は以前理解していた回文とは異なり、例は以下の通りです.
['deltas','desalt','lasted','salted','slated','staled']
['retainers','ternaries']
同じアルファベットで構成された単語がすべて回文の単語集合に含まれている限り
肝心な情報をつかんで自分がすでに掌握した方法の原則に転化して、私は2つの大体の方向があって、1つは1つずつ各単語を読んで、単語を前に言ったアルファベットの語周波数カウンタで単語を分解して、もし語周波数のカウントが同じならば1つの集合の中に置きます;もう一つの方向は26文字を並べて組み合わせて各単語を構成して単語表に比較することであり、明らかに2番目の方法は最初の原則に違反している.これは私の現在の掌握の中ではなく、特に複雑で、計算量が大きいからだ.
しかし、後でもっと簡単な方法が発見されたのは、すでに身につけているソート機能を利用して、単語のアルファベットを分解してソートし、結果が同じなら1つの集合に置くことだ.
def paixu_pinjie(word):
    t=list(word)
    t.sort()
    a=''.join(t)
    return a

fin=open('words.txt')
d=dict()
for line in fin:
    word=line.strip()
    b=paixu_pinjie(word)
    if b not in d:
        d[b]=word
    else:
        d[b].append(word)
return d

for key,val in d.items():
    if len(val)>1:
        print(val)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
 in async-def-wrapper()
     17 return d
     18 
---> 19 for key,val in d.items():
     20     if len(val)>1:
     21         print(val)

AttributeError: 'str' object has no attribute 'append'

ここで問題が発見されたのはd[b]=wordで、wordは文字列なのでappendは使用できません.後に単語プログラミング単語の集合を追加するには、wordをリストにする必要があります.
def paixu_pinjie(word):
    t=list(word)
    t.sort()
    a=''.join(t)
    return a

fin=open('words.txt')
d=dict()
for line in fin:
    word=line.strip()
    b=paixu_pinjie(word)
    if b not in d:
        d[b]=[word]
    else:
        d[b].append(word)
return d

for key,val in d.items():
    if len(val)>1:
        print(val)

これは間違いではありませんが、出力結果に単語の集合があることがわかりました.明らかに最後のforループの後のコードが有効ではありません.forの上のreturnによるもので、returnは関数でしか使用できません.現在、2つの解決策があります.1つはこのreturnを削除し、もう1つは上のものを1つの関数として書きます.
def paixu_pinjie(word):
    t=list(word)
    t.sort()
    a=''.join(t)
    return a

def all_anagrams(filename):
    fin=open(filename)
    d=dict()
    for line in fin:
        word=line.strip().lower()
        b=paixu_pinjie(word)
        if b not in d:
            d[b]=[word]
        else:
            d[b].append(word)
    return d
def print_anagram_set(d):
    for key,val in d.items():
        if len(val)>1:
            print(val)

d=all_anagrams('words.txt')
print_anagram_set(d)

上のコードを関数に変更し、word=line.strip()の後ろに追加しました.lower()は、大文字を小文字にする必要があります.1つのコードを関数に書くかどうかを決定する原則は、このコードが繰り返し使用されるかどうか、そしてこのコードが単独で取り外されてもよいかどうかです.
前の問題のプログラムを修正し,集合内の単語数に従って逆順に印刷する.
def print_anagram_sets_in_order(d):
    t=list() #          
    for key,val in d.items():
        if len(val)>1:
            t.append((len(val),val))
    t.sort(reverse=True) #  
    #     
    for x in t:
        print(x)
print_anagram_sets_in_order(d)

後で上の部分コードを再使用する必要があるので、その一部を関数に変換する必要があります.そうしないと、もう一度書かなければなりません.
2.choose_を作成するfrom_histは、パラメータとしてヒストグラムを受け入れ、ヒストグラムから周波数サイズに比例してランダムに値を返します.
ヒストグラムは「python独学日記7-辞書」に書いてありますが、これを通じて良いpython学習資料について質問されたことを思い出し、良い学習資料の一つに前後の知識点を練習問題の形式でつなぐことができることを決めました.他の人はまた一人で時間を見つけて一緒に話します.
ヒストグラム関数はとっくに書いてありますが、残りは確率に基づいてランダムに値を取ります.公式ドキュメントからrandomのchoicesがこの要件を満たしていることがわかります.重要なパラメータweightsは、リストの中でweightsの後ろのリストの各数が総数を占める確率に基づいて値を取ることができます.具体的には、この例では、ヒストグラムから、アルファベットと対応するアルファベットに現れていない語周波数を含む辞書が得られます.辞書のキーと値を2つのリストに分けることができます.キーのリストはランダムな値のリストとして、値のリストはweightsに前の値の確率として与えられ、以下のコードが得られる.
def histogram(s):
    d=dict()
    for c in s:
        d[c]=int(d.get(c,'0'))+1  #get          ,         ,      ,       
    return d
def choose_from_hist(s):
    d=histogram(s) #                   
    a=[] 
    b=[]
    for key,val in d.items():
        a.append(key)
        b.append(val)
    print(a) #    
    print(b) #    
    return random.choices(a,weights=b,k=20)
h=histogram('aaaaaabb')        
choose_from_hist(h)
['a', 'b']
[1, 1]

その結果,戻り値中値リストは本来[6,2]のはずであるが,[1,1]であり,ヒストグラム関数が2回実行され,すなわちヒストグラム関数がパラメータとして伝達され,1回ヒストグラム関数が実行されていることが分かった.関数内でヒストグラムコードを実行するだけでいいです
def histogram(s):
    d=dict()
    for c in s:
        d[c]=int(d.get(c,'0'))+1
    return d


def choose_from_hist(s):
    a=[]
    b=[]
    for key,val in d.items():
        a.append(key)
        b.append(val)
    print(a)
    print(b)
    return random.choices(a,weights=b,k=5) #k    k    
h=histogram('aaaaaabb')        
choose_from_hist(h)
['a', 'b']
[6, 2]

Out[85]:
['a', 'a', 'a', 'a', 'b']