sorted【ソート】enumerate【番号付け】reversed【逆順】zip【組分け】3.10 sorted【ソート】メモソート 〔 例 〕 元オブジェクトは変更なし ( list【リスト型】の sort【ソート】は元を変更 ) 順序関数の指定可 逆順の指定可 ソートの安定性 〔 例 〕 ソート対象が同じ場合、元の順序を保持 複合的なソート可能:優先順位が低いものから逆に続けてソート (下記の operator モジュール関数も参照) 複数要素の集まり(C系言語の構造体相当) をソート 〔 例 〕operator:operator モジュール関数 (高速のアクセサ関数) ソート対象関数・演算備考名前指定の属性 item.attr 参照:指定属性の値item:要素attr:属性名operator.attrgetter(attr) 戻り値:指定属性の値attr:属性名operator.attrgetter(*attrs) 戻り値:指定属性値のタプルattrs:属性名 (複合的なソート)インデックス指定の要素 item[i] 参照:指定要素の値item:要素i:要素のインデックスoperator.itemgetter(item) 戻り値:指定要素の値item:要素のインデックスoperator.itemgetter(*items) 戻り値:指定要素値のタプルitems:要素のインデックス (複合的なソート)要素メソッドの戻り値operator.methodcaller(name[, args...]) 戻り値:メソッドの戻り値name:メソッド名args:メソッドの引数関連 Python 標準ライブラリ組み込み関数sorted(iterable, *, key=None, reverse=False) operator --- 関数形式の標準演算子operator.attrgetter(attr)operator.itemgetter(item)operator.methodcaller(name[, args...]) Python HOWTOソート HOW TO 構文 sorted(iterable, *, key=None, reverse=False) 戻り値リスト (list【リスト型】参照) iterableイテラブル オブジェクト key (キーワード引数)順序関数 (省略:要素をそのまま比較 / 詳細は下記参照) reverse (キーワード引数)反転フラグ (True:降順 / False:昇順) ※ 構文の * は、キーワード引数との区切り (def【関数定義】 参照) 順序関数 引数名 (例)説明item要素戻り値説明比較用キー 例 (ソート) def func(item): return abs(item) # 参考:list【リスト型】の sort【ソート】 lst = [1, -2, 3, -4, 5] print(lst) # 出力:[1, -2, 3, -4, 5] lst.sort() print(lst) # 出力:[-4, -2, 1, 3, 5] lst = [1, -2, 3, -4, 5] sort1 = sorted(lst) sort2 = sorted(lst, reverse=True) sort3 = sorted(lst, key=func) sort4 = sorted(lst, key=func, reverse=True) print(lst) # 出力:[1, -2, 3, -4, 5] 【変更なし】 print(sort1) # 出力:[-4, -2, 1, 3, 5] print(sort2) # 出力:[5, 3, 1, -2, -4] print(sort3) # 出力:[1, -2, 3, -4, 5] print(sort4) # 出力:[5, -4, 3, -2, 1] tpl = ('a', 'B', 'c', 'D', 'e') sort1 = sorted(tpl) sort2 = sorted(tpl, reverse=True) sort3 = sorted(tpl, key=str.lower) sort4 = sorted(tpl, key=str.lower, reverse=True) print(tpl) # 出力:('a', 'B', 'c', 'D', 'e') 【変更なし】 print(sort1) # 出力:['B', 'D', 'a', 'c', 'e'] print(sort2) # 出力:['e', 'c', 'a', 'D', 'B'] print(sort3) # 出力:['a', 'B', 'c', 'D', 'e'] print(sort4) # 出力:['e', 'D', 'c', 'B', 'a'] dic = {'a': 1, 'c': 3, 'b': -2, 'd': -4, 'e': 5} # キーのみソート (1) key_1 = sorted(dic) print(key_1) # 出力:['a', 'b', 'c', 'd', 'e'] key_r1 = sorted(dic, reverse=True) print(key_r1) # 出力:['e', 'd', 'c', 'b', 'a'] # キーのみソート (2) key_2 = sorted(dic.keys()) print(key_2) # 出力:['a', 'b', 'c', 'd', 'e'] key_r2 = sorted(dic.keys(), reverse=True) print(key_r2) # 出力:['e', 'd', 'c', 'b', 'a'] # 値のみソート value = sorted(dic.values()) print(value) # 出力:[-4, -2, 1, 3, 5] value_r = sorted(dic.values(), reverse=True) print(value_r) # 出力:[5, 3, 1, -2, -4] # キーでソート (1) list_key = sorted(dic.items()) print(list_key) # 出力:[('a', 1), ('b', -2), ('c', 3), ('d', -4), ('e', 5)] dic_key = dict(list_key) print(dic_key) # 出力:{'a': 1, 'b': -2, 'c': 3, 'd': -4, 'e': 5} # キーでソート (1) 降順 list_key_r = sorted(dic.items(), reverse=True) print(list_key_r) # 出力:[('e', 5), ('d', -4), ('c', 3), ('b', -2), ('a', 1)] dic_key_r = dict(list_key_r) print(dic_key_r) # 出力:{'e': 5, 'd': -4, 'c': 3, 'b': -2, 'a': 1} # キーでソート (2) list_key2 = sorted(dic.items(), key=lambda x: x[0]) print(list_key2) # 出力:[('a', 1), ('b', -2), ('c', 3), ('d', -4), ('e', 5)] dic_key2 = dict(list_key2) print(dic_key2) # 出力:{'a': 1, 'b': -2, 'c': 3, 'd': -4, 'e': 5} # キーでソート (2) 降順 list_key2_r = sorted(dic.items(), key=lambda x: x[0], reverse=True) print(list_key2_r) # 出力:[('e', 5), ('d', -4), ('c', 3), ('b', -2), ('a', 1)] dic_key2_r = dict(list_key2_r) print(dic_key2_r) # 出力:{'e': 5, 'd': -4, 'c': 3, 'b': -2, 'a': 1} # 値でソート list_value = sorted(dic.items(), key=lambda x: x[1]) print(list_value) # 出力:[('d', -4), ('b', -2), ('a', 1), ('c', 3), ('e', 5)] dic_value = dict(list_value) print(dic_value) # 出力:{'d': -4, 'b': -2, 'a': 1, 'c': 3, 'e': 5} # 値でソート 降順 list_value_r = sorted(dic.items(), key=lambda x: x[1], reverse=True) print(list_value_r) # 出力:[('e', 5), ('c', 3), ('a', 1), ('b', -2), ('d', -4)] dic_value_r = dict(list_value_r) print(dic_value_r) # 出力:{'e': 5, 'c': 3, 'a': 1, 'b': -2, 'd': -4} # 辞書のリスト list_dic = [ {'KEY1': 3, 'KEY2': 20}, {'KEY1': 1, 'KEY2': 10}, {'KEY1': 2, 'KEY2': 30}, ] list_key1 = sorted(list_dic, key=lambda x: x['KEY1']) print(list_key1) # 出力:[{'KEY1': 1, 'KEY2': 10}, {'KEY1': 2, 'KEY2': 30}, {'KEY1': 3, 'KEY2': 20}] list_key1_r = sorted(list_dic, key=lambda x: x['KEY1'], reverse=True) print(list_key1_r) # 出力:[{'KEY1': 3, 'KEY2': 20}, {'KEY1': 2, 'KEY2': 30}, {'KEY1': 1, 'KEY2': 10}] list_key2 = sorted(list_dic, key=lambda x: x['KEY2']) print(list_key2) # 出力:[{'KEY1': 1, 'KEY2': 10}, {'KEY1': 3, 'KEY2': 20}, {'KEY1': 2, 'KEY2': 30}] list_key2_r = sorted(list_dic, key=lambda x: x['KEY2'], reverse=True) print(list_key2_r) # 出力:[{'KEY1': 2, 'KEY2': 30}, {'KEY1': 3, 'KEY2': 20}, {'KEY1': 1, 'KEY2': 10}] 例 (ソートの安定性) def display(itr): for tpl in itr: print(tpl) print() persons = [ ('001', 'Bob', 'M', 'Tokyo'), ('002', 'Liz', 'F', 'Tokyo'), ('003', 'Tom', 'M', 'Osaka'), ('004', 'May', 'F', 'Osaka'), ] # インデックス 2 でソート sort1 = sorted(persons, key=lambda item: item[2]) # 出力はインデックス 2のみでソート display(sort1) # 出力:('002', 'Liz', 'F', 'Tokyo') # 出力:('004', 'May', 'F', 'Osaka') # 出力:('001', 'Bob', 'M', 'Tokyo') # 出力:('003', 'Tom', 'M', 'Osaka') # インデックス 3 でソート sort2 = sorted(persons, key=lambda item: item[3]) # 続けてインデックス 2 でソート sort1 = sorted(sort2, key=lambda item: item[2]) # 出力はインデックス 2・3 でソート display(sort1) # 出力:('004', 'May', 'F', 'Osaka') # 出力:('002', 'Liz', 'F', 'Tokyo') # 出力:('003', 'Tom', 'M', 'Osaka') # 出力:('001', 'Bob', 'M', 'Tokyo') 例 (複数要素の集まりをソート) # 名前指定の属性 from operator import attrgetter def display(itr): for tpl in itr: print(tpl) print() class Person: def __init__(self, id, name, sex, address): self.id = id self.name = name self.sex = sex self.address = address def __repr__(self): return repr((self.id, self.name, self.sex, self.address)) persons = [ Person('001', 'Bob', 'M', 'Tokyo'), Person('002', 'Liz', 'F', 'Tokyo'), Person('003', 'Tom', 'M', 'Osaka'), Person('004', 'May', 'F', 'Osaka'), ] display(sorted(persons, key=lambda person: person.id)) # 出力:下記と同じ display(sorted(persons, key=attrgetter('id'))) # 出力:('001', 'Bob', 'M', 'Tokyo') # 出力:('002', 'Liz', 'F', 'Tokyo') # 出力:('003', 'Tom', 'M', 'Osaka') # 出力:('004', 'May', 'F', 'Osaka') display(sorted(persons, key=lambda person: person.name)) # 出力:下記と同じ display(sorted(persons, key=attrgetter('name'))) # 出力:('001', 'Bob', 'M', 'Tokyo') # 出力:('002', 'Liz', 'F', 'Tokyo') # 出力:('004', 'May', 'F', 'Osaka') # 出力:('003', 'Tom', 'M', 'Osaka') display(sorted(persons, key=lambda person: person.sex)) # 出力:下記と同じ display(sorted(persons, key=attrgetter('sex'))) # 出力:('002', 'Liz', 'F', 'Tokyo') # 出力:('004', 'May', 'F', 'Osaka') # 出力:('001', 'Bob', 'M', 'Tokyo') # 出力:('003', 'Tom', 'M', 'Osaka') display(sorted(persons, key=lambda person: person.address)) # 出力:下記と同じ display(sorted(persons, key=attrgetter('address'))) # 出力:('003', 'Tom', 'M', 'Osaka') # 出力:('004', 'May', 'F', 'Osaka') # 出力:('001', 'Bob', 'M', 'Tokyo') # 出力:('002', 'Liz', 'F', 'Tokyo') display(sorted(persons, key=attrgetter('sex', 'address'))) # 出力:('004', 'May', 'F', 'Osaka') # 出力:('002', 'Liz', 'F', 'Tokyo') # 出力:('003', 'Tom', 'M', 'Osaka') # 出力:('001', 'Bob', 'M', 'Tokyo') # インデックス指定の要素 from operator import itemgetter def display(itr): for tpl in itr: print(tpl) print() persons = [ ('001', 'Bob', 'M', 'Tokyo'), ('002', 'Liz', 'F', 'Tokyo'), ('003', 'Tom', 'M', 'Osaka'), ('004', 'May', 'F', 'Osaka'), ] display(sorted(persons, key=lambda person: person[0])) # 出力:下記と同じ display(sorted(persons, key=itemgetter(0))) # 出力:('001', 'Bob', 'M', 'Tokyo') # 出力:('002', 'Liz', 'F', 'Tokyo') # 出力:('003', 'Tom', 'M', 'Osaka') # 出力:('004', 'May', 'F', 'Osaka') display(sorted(persons, key=lambda person: person[1])) # 出力:下記と同じ display(sorted(persons, key=itemgetter(1))) # 出力:('001', 'Bob', 'M', 'Tokyo') # 出力:('002', 'Liz', 'F', 'Tokyo') # 出力:('004', 'May', 'F', 'Osaka') # 出力:('003', 'Tom', 'M', 'Osaka') display(sorted(persons, key=lambda person: person[2])) # 出力:下記と同じ display(sorted(persons, key=itemgetter(2))) # 出力:('002', 'Liz', 'F', 'Tokyo') # 出力:('004', 'May', 'F', 'Osaka') # 出力:('001', 'Bob', 'M', 'Tokyo') # 出力:('003', 'Tom', 'M', 'Osaka') display(sorted(persons, key=lambda person: person[3])) # 出力:下記と同じ display(sorted(persons, key=itemgetter(3))) # 出力:('003', 'Tom', 'M', 'Osaka') # 出力:('004', 'May', 'F', 'Osaka') # 出力:('001', 'Bob', 'M', 'Tokyo') # 出力:('002', 'Liz', 'F', 'Tokyo') display(sorted(persons, key=itemgetter(2, 3))) # 出力:('004', 'May', 'F', 'Osaka') # 出力:('002', 'Liz', 'F', 'Tokyo') # 出力:('003', 'Tom', 'M', 'Osaka') # 出力:('001', 'Bob', 'M', 'Tokyo') from operator import methodcaller lst = ['ABACA', 'ABABA', 'ABACA', 'AAAAA', 'AABAA', 'BBACC'] # A が多い順 print(sorted(lst, key=methodcaller("count", 'A'), reverse=True)) # 出力:['AAAAA', 'AABAA', 'ABACA', 'ABABA', 'ABACA', 'BBACC'] # A が多い順、次にB が多い順 sortb = sorted(lst, key=methodcaller("count", 'B'), reverse=True) print(sorted(sortb, key=methodcaller("count", 'A'), reverse=True)) # 出力:['AAAAA', 'AABAA', 'ABABA', 'ABACA', 'ABACA', 'BBACC'] enumerate【番号付け】メモ要素に番号(連番)付け 元のオブジェクトは変更なし 関連 enum【列挙型】 外部リンク Python 標準ライブラリ組み込み関数enumerate(iterable, start=0) 構文 enumerate(iterable, start=0) 戻り値タプル(番号, 要素)のイテレータ iterable下記オブジェクト シーケンス イテレータ イテレーション サポート オブジェクト start開始整数番号 (省略:0) 例 lst = ['a', 'b', 'c'] itr0 = enumerate(lst) itrx = enumerate(lst, 1) print(lst) # 出力:['a', 'b', 'c'] print(list(itr0)) # 出力:[(0, 'a'), (1, 'b'), (2, 'c')] print(list(itrx)) # 出力:[(1, 'a'), (2, 'b'), (3, 'c')] tpl = ('A', 'B', 'C') itr0 = enumerate(tpl) itrx = enumerate(tpl, 2) print(tpl) # 出力:('A', 'B', 'C') print(list(itr0)) # 出力:[(0, 'A'), (1, 'B'), (2, 'C')] print(list(itrx)) # 出力:[(2, 'A'), (3, 'B'), (4, 'C')] dic = {'a': 'A', 'b': 'B', 'c': 'C'} itr0 = enumerate(dic) itrx = enumerate(dic, -1) print(dic) # 出力:{'a': 'A', 'b': 'B', 'c': 'C'} print(list(itr0)) # 出力:[(0, 'a'), (1, 'b'), (2, 'c')] print(list(itrx)) # 出力:[(-1, 'a'), (0, 'b'), (1, 'c')] s = "abc" itr0 = enumerate(s) itrx = enumerate(s, -2) print(s) # 出力:abc print(list(itr0)) # 出力:[(0, 'a'), (1, 'b'), (2, 'c')] print(list(itrx)) # 出力:[(-2, 'a'), (-1, 'b'), (0, 'c')] reversed【逆順】メモ該当オブジェクトを逆順にする 元のオブジェクトは変更なし dict【辞書型】・辞書ビュー も対応 3.8 関連 list【リスト型】 tuple【タプル型】 Python 標準ライブラリ組み込み関数reversed(seq) 構文 reversed(seq) 戻り値逆順イテレータ seq下記対応オブジェクト __reversed__() メソッド 対応オブジェクト シーケンス型プロトコル サポート オブジェクト ( __len__() メソッド・__getitem__(0 以上の整数) メソッド 対応) 例 lst = [1, 2, 3, 4, 5] itr = reversed(lst) print(lst) # 出力:[1, 2, 3, 4, 5] print(list(itr)) # 出力:[5, 4, 3, 2, 1] tpl = ('A', 'B', 'C', 'D') itr = reversed(tpl) print(list(tpl)) # 出力:['A', 'B', 'C', 'D'] print(list(itr)) # 出力:['D', 'C', 'B', 'A'] s = "abcd" itr = reversed(s) print(list(s)) # 出力:['a', 'b', 'c', 'd'] print(list(itr)) # 出力:['d', 'c', 'b', 'a'] rng = range(1, 9, 2) itr = reversed(rng) print(list(rng)) # 出力:[1, 3, 5, 7] print(list(itr)) # 出力:[7, 5, 3, 1] # 以降 Python 3.8 dic = {'Key1': 'Value1', 'Key2': 'Value2', 'Key3': 'Value3'} for key in dic: print(key) # 出力:Key1 # 出力:Key2 # 出力:Key3 for key in reversed(dic): print(key) # 出力:Key3 # 出力:Key2 # 出力:Key1 for key in dic.keys(): print(key) # 出力:Key1 # 出力:Key2 # 出力:Key3 for key in reversed(dic.keys()): print(key) # 出力:Key3 # 出力:Key2 # 出力:Key1 for value in dic.values(): print(value) # 出力:Value1 # 出力:Value2 # 出力:Value3 for value in reversed(dic.values()): print(value) # 出力:Value3 # 出力:Value2 # 出力:Value1 for key, value in dic.items(): print(key, value) # 出力:Key1 Value1 # 出力:Key2 Value2 # 出力:Key3 Value3 for key, value in reversed(dic.items()): print(key, value) # 出力:Key3 Value3 # 出力:Key2 Value2 # 出力:Key1 Value1 class Reversed(): def __iter__(self): return iter("NORMAL") def __reversed__(self): return iter("REVERSED") class Alphabet(): def __init__(self, length): self.length = length def __iter__(self): lst = [chr(0x41 + index) for index in range(self.length)] return iter(lst) def __len__(self): return self.length def __getitem__(self, key): return chr(0x41 + key) rev = Reversed() itr = reversed(rev) print(list(rev)) # 出力:['N', 'O', 'R', 'M', 'A', 'L'] print(list(itr)) # 出力:['R', 'E', 'V', 'E', 'R', 'S', 'E', 'D'] alph = Alphabet(5) itr = reversed(alph) print(list(alph)) # 出力:['A', 'B', 'C', 'D', 'E'] print(list(itr)) # 出力:['E', 'D', 'C', 'B', 'A'] zip【組分け】3.10メモイテラブルを順に組(タプル)分け 元のイテラブルは変更なし 要素数が違う場合、最小の要素数まで( strict (厳密性)3.10 指定で、要素数が不一致の場合のどう) list【リスト型】のリスト内包表記内の使用で、 list【リスト型】・tuple【タプル型】の生成可 最大要素数に合わせるには、標準ライブラリの itertools.zip_longest() を使用 関連 tuple【タプル型】 list【リスト型】 外部リンク Python 標準ライブラリ組み込み関数zip(*iterables) itertools.zip_longest(*iterables, fillvalue=None) 構文 zip(*iterables, strict3.10 =False) 戻り値tuple【タプル型】(組分け)のイテレータ 例外設定された場合、要素不足のアクセスで例外発生 iterablesイテラブル オブジェクト (デフォルト:指定数により下記を返却) 未指定空のイテレータ 1個指定1要素のタプルのイテレータ 2個以上指定組(タプル)のイテレータ (要素数:最小の要素数) strict3.10厳密性 (要素数) True要素数が不一致の場合、戻り値のイテレータに例外設定 False要素数が不一致の場合、最小要素数 (iterables 参照) 例 (基本) lst = [1, 2, 3] tpl = ('A', 'B', 'C', 'D') s = "abcde" itr = zip() print(list(itr)) # 出力:[] itr = zip(lst) print(list(itr)) # 出力:[(1,), (2,), (3,)] itr = zip(lst, tpl) print(list(itr)) # 出力:[(1, 'A'), (2, 'B'), (3, 'C')] itr = zip(lst, tpl, s) print(list(itr)) # 出力:[(1, 'A', 'a'), (2, 'B', 'b'), (3, 'C', 'c')] print(lst) # 出力:[1, 2, 3] print(tpl) # 出力:('A', 'B', 'C', 'D') print(s) # 出力:abcde 例 (リスト内包表記内の使用) # list lst1 = [1, 2, 3, 4] lst2 = [2, 3, 4, 5] lst3 = [x + y for x, y in zip(lst1, lst2)] lst4 = [x * y for x, y in zip(lst1, lst2)] print(lst1) # 出力:[1, 2, 3, 4] print(lst2) # 出力:[2, 3, 4, 5] print(lst3) # 出力:[3, 5, 7, 9] print(lst4) # 出力:[2, 6, 12, 20] # tuple tpl1 = (1, 2, 3, 4) tpl2 = (2, 3, 4, 5) tpl3 = tuple([x + y for x, y in zip(tpl1, tpl2)]) tpl4 = tuple([x * y for x, y in zip(tpl1, tpl2)]) print(tpl1) # 出力:(1, 2, 3, 4) print(tpl2) # 出力:(2, 3, 4, 5) print(tpl3) # 出力:(3, 5, 7, 9) print(tpl4) # 出力:(2, 6, 12, 20) 例 (厳密性) lst = [1, 2, 3] tpl = ('A', 'B', 'C', 'D') s = "abcde" itr = zip(strict=True) print(list(itr)) # 出力:[] itr = zip(lst, strict=True) for item in itr: print(item) # 出力:(1,) # 出力:(2,) # 出力:(3,) itr = zip(tpl, tpl, strict=True) for item in itr: print(item) # 出力:('A', 'A') # 出力:('B', 'B') # 出力:('C', 'C') # 出力:('D', 'D') itr = zip(lst, tpl) for item in itr: print(item) # 出力:(1, 'A') # 出力:(2, 'B') # 出力:(3, 'C') itr = zip(lst, tpl, strict=True) try: for item in itr: print(item) except ValueError as e: print(e) # 出力:(1, 'A') # 出力:(2, 'B') # 出力:(3, 'C') # 出力:zip() argument 2 is longer than argument 1 itr = zip(tpl, lst, s) for item in itr: print(item) # 出力:('A', 1, 'a') # 出力:('B', 2, 'b') # 出力:('C', 3, 'c') itr = zip(tpl, lst, s, strict=True) try: for item in itr: print(item) except ValueError as e: print(e) # 出力:('A', 1, 'a') # 出力:('B', 2, 'b') # 出力:('C', 3, 'c') # 出力:zip() argument 2 is shorter than argument 1 例 (最大要素数合わせ) import itertools lst = [1, 2, 3] tpl = ('A', 'B', 'C', 'D') s = "abcde" itr = itertools.zip_longest(lst, tpl, fillvalue='FILL') print(list(itr)) # 出力:[(1, 'A'), (2, 'B'), (3, 'C'), ('FILL', 'D')] itr = itertools.zip_longest(lst, tpl, s, fillvalue='FILL') print(list(itr)) # 出力:[(1, 'A', 'a'), (2, 'B', 'b'), (3, 'C', 'c'), ('FILL', 'D', 'd'), ('FILL', 'FILL', 'e')]