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

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, '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【番号付け】

メモ

構文

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]
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

メモ

構文

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')]