Pythonプログラミング

【Python】10.リスト(4)高度なリスト操作

リストは入れ子にする事ができます。入れ子の事はネストとも呼びます。
あるリストの中に他のリストを入れてみましょう。
まずは三国志の各陣営の主要人物リストを作ってみます。

sangoku = [["劉備","関羽","張飛"], ["曹操","夏侯惇","張遼"],[ "孫権","程普","甘寧"]]
print(sangoku)

出力結果
[[‘劉備’, ‘関羽’, ‘張飛’], [‘曹操’, ‘夏侯惇’, ‘張遼’], [‘孫権’, ‘程普’, ‘甘寧’]]

リストが入れ子になってもエラーにならない事がわかります。
次に、それぞれのリストを変数にして代入してみます。

gi = ["曹操","夏侯惇","張遼"]
go = [ "孫権","程普","甘寧"]
syoku = ["劉備","関羽","張飛"]
sangoku = [gi, go, syoku]
print(sangoku)
#2番目のリストの3番目の要素だけ出力
print(sangoku[1][2])
#要素の数を数える
print(len(sangoku))
#リストの中身を変数として入れ替える
gi = ["荀彧", "郭嘉", "陳宮"]
print(gi)
#一つのリストに他のリストの中身を代入する
gi = [gi[0],go[1],syoku[2]]
print(gi)

上のように、ネストされたリストの一部だけを参照したり、変数として代入する事ができます。

ループでリストを処理する

リストから要素を取り出すにはループを使います。
ついでに番号をつけてみます。

syoku = ["劉備","関羽","張飛"]
for (i,busyou) in enumerate(syoku):
    print("蜀の" + str(i + 1) + "人目の武将、" + busyou + "が現れた!")

出力結果)
蜀の1人目の武将、劉備が現れた!
蜀の2人目の武将、関羽が現れた!
蜀の3人目の武将、張飛が現れた!

このようにリストの要素を順番に処理する事ができます。
順番は0から始まるので+1しています。
次はの数値に5倍した値をappend関数を使ってリストに格納してみましょう。
数字だけを扱う場合はダブルクォーテーションはいりません。

numbers = [3,1,4,1,5]
results = []
for i in numbers:
    results.append(i * 10)
print(results)

出力結果)
[5, 10, 15, 20, 25]

次はちょっと応用して、for文で生成した数字をリストに格納してみます。

#変数内でループでリストを作成
no = [1 for i in range(10)]
print(no)
#変数内でループ内で四則演算してリストを作成
no = [i * 3  for i in range(10)]
print(no)

ところで、for文は「直前の処理を繰り返す」という関数です。
「1 for i in range(3)」とすると、1を3回繰り返します。
これをさらに繰り返すと、for文でネストされたリストを生成する事ができます。
例として、1を3回繰り返しして出力するのを、4回繰り返してみます。

no1_3_4 = [[1  for i in range(3)] for j in range(4)]
print(no1_3_4 )

出力結果)
[[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]]

for文で生成されたリストのネストを作る事ができました!

ソート

リストはソートできないと不便ですよね。
Pythonでリストをソートするにはsort()とsorted()の2つの関数があります。
この時、文字列やタプルをソートしたい場合はsorted()を使います。
整列する順番は、あいうえお順か、数字があれば数字順、漢字だと文字コードの並びが自動的にあてはめられます。
この「勝手に決まっている」というのがPythonの特徴ですよね・・・。

ryouchi = ["はりま", "むさし", "やまと", "すおう"]
print("普通に出力")
print(ryouchi)
print("ソートして出力")
print(sorted(ryouchi))


領地という変数を作り、播磨、武蔵、大和、周防を格納します。
まずは、普通に出力してみます。
次に、ソートして出力します。

出力結果)
普通に出力
[‘はりま’, ‘むさし’, ‘やまと’, ‘すおう’]
ソートして出力
[‘すおう’, ‘はりま’, ‘むさし’, ‘やまと’]

ひらがなが並べ替えられたのがわかります!
次に、降順にしてみましょう。反転はreverseを使います。
今度は数字にしてみます。石高は慶長三年時の石高を入力してみましょう。

kokudaka = [358534,667126, 448945,167820]
print(sorted(kokudaka))
print("順逆にします")
print(sorted(kokudaka,reverse=True))

出力結果)
[167820, 358534, 448945, 667126]
順逆にします
[667126, 448945, 358534, 167820]

逆になったのがわかりますでしょうか。
周防国の石高って低いんですね・・・。これで徳川と戦った毛利氏はすごいですね。

標準入力とリストを使って複数行を読み込む

次は、標準入力とリストを組み合わせて、少佐の演説を出力してみましょう。
そのまんまは倫理的にどうかと思うので、少し変更します。
(どっちにしてもどうかと思われそうですが)

import sys
enzetsu = []
for text in sys.stdin.readlines():
    msg = text.rstrip()
    print("諸君、私は" + msg + "が好きだ")
  1. sysモジュールを読み込み
  2. 空のリストを作る
  3. For文開始。textという名前でsysの標準入力で入力されたテキストを1行づつ読み込み
  4. enzetsuという変数を作り、lineの中身を右側削除で代入
  5. 出力

入力例)
殲滅戦
電撃戦
打撃戦
防衛戦
包囲戦
突破戦
退却戦
掃討戦
撤退戦

出力結果)
諸君、私は殲滅戦が好きだ
諸君、私は電撃戦が好きだ
諸君、私は打撃戦が好きだ
諸君、私は防衛戦が好きだ
諸君、私は包囲戦が好きだ
諸君、私は突破戦が好きだ
諸君、私は退却戦が好きだ
諸君、私は掃討戦が好きだ
諸君、私は撤退戦が好きだ

鉄風雷火の限りを尽くし、三千世界の鴉を殺す!
少佐の演説はやはり元のままが一番だという事がわかりますね!

リストに番号を付加する

最後は、リストに格納している内容に番号をつけてみましょう。

enumerate関数

enumerate関数は、要素のインデックスと要素を同時に取り出す事が出来ます。
例として、蜀の五虎大将のリストに背番号を振ってみましょう。

goko= ["関羽",
        "張飛",
        "馬超",
        "趙雲",
    "黄忠"]
for i,busyou in enumerate(goko):
    print("五虎大将 No." + str(i + 1) + "・",end="")
    for name in busyou:
        print(name,end="")
    print()
  1. リストを作成します。
  2. for文開始。変数1をI、2をlineとします。これにenumerate関数を適用し、引数は上記のリストgokoを適用します。
  3. プリントを行います。インデックスは0から始まるので、iに1を加算した値を文字として出力し、改行無しにするためendを何も無しにします。次に処理される時は1加算されます。
  4. for文内でさらにfor文を開始。変数はnameでbusyouを読み出します。
    enumerateの第2引数であるbusyouをnameとして出力し、改行無しにします。
  5. インデックス(に+1したもの)とリストを出力した後は改行したいので、何もない出力を行って改行します。

出力結果)
五虎大将 No.1・関羽
五虎大将 No.2・張飛
五虎大将 No.3・馬超
五虎大将 No.4・趙雲
五虎大将 No.5・黄忠

リストに番号がつきました!
関羽は他の将と並べられるのが嫌かも知れませんけどね。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です