sorted()【ソート】
enumerate()【番号付け】
reversed()【逆順】
zip()【組分け】

sorted()【ソート】

メモ

  • ソート
  • ソートの安定性
    • ソート対象が同じ場合、元の順序を保持
    • 複合的なソート可能:優先順位が低いものから逆に続けてソート (下記の 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:メソッドの引数
  • 関連

構文

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, 'b': -2, 'c': 3, 'd': -4, 'e': 5}
#     {'d': -4, 'b': -2, 'a': 1, 'c': 3, 'e': 5} 値でソート
sort1 = sorted(dic)
sort2 = sorted(dic, reverse=True)
sort3 = sorted(dic, key=lambda key_: dic[key_])
sort4 = sorted(dic, key=lambda key_: dic[key_], reverse=True)
print(dic)    # 出力:{'a': 1, 'b': -2, 'c': 3, 'd': -4, 'e': 5} 【変更なし】
print(sort1)  # 出力:['a', 'b', 'c', 'd', 'e'] キーでソート
print(sort2)  # 出力:['e', 'd', 'c', 'b', 'a'] キーでソート (降順)
print(sort3)  # 出力:['d', 'b', 'a', 'c', 'e'] 値でソート
print(sort4)  # 出力:['e', 'c', 'a', 'b', 'd'] 値でソート (降順)

例 (ソートの安定性)

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()【番号付け】

メモ

構文

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()【逆順】

メモ

構文

reversed(seq)

戻り値逆順イテレータ
seq下記対応オブジェクト
__reversed__() メソッド 対応オブジェクト
シーケンス型プロトコル サポート オブジェクト ( __len__() メソッド・__getitem__(0 以上の整数) メソッド 対応)

lst = [1, 2, 3, 4, 5]
tpl = ('A', 'B', 'C', 'D')
s = "abcd"
rng = range(1, 9, 2)

itr = reversed(lst)
print(lst)        # 出力:[1, 2, 3, 4, 5]
print(list(itr))  # 出力:[5, 4, 3, 2, 1]

itr = reversed(tpl)
print(list(tpl))  # 出力:['A', 'B', 'C', 'D']
print(list(itr))  # 出力:['D', 'C', 'B', 'A']

itr = reversed(s)
print(list(s))    # 出力:['a', 'b', 'c', 'd']
print(list(itr))  # 出力:['d', 'c', 'b', 'a']

itr = reversed(rng)
print(list(rng))  # 出力:[1, 3, 5, 7]
print(list(itr))  # 出力:[7, 5, 3, 1]
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()【組分け】

メモ

構文

zip(*iterables)

戻り値タプル(組分け)のイテレータ
iterablesイテラブル オブジェクト (指定数により下記を返却)
未指定空のイテレータ
1個指定1要素のタプルのイテレータ
2個以上指定組(タプル)のイテレータ (要素数:最小の要素数)

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