LoginSignup
6
6

More than 5 years have passed since last update.

Python sorted

Last updated at Posted at 2014-05-21

ソートするデーター

ID 名前 国語 英語
0001 A 10 40
0003 B 30 20
0002 D 40 30
0004 C 20 10

データーを格納する汎用基底クラスを作成

参考文献

Happy Programming » Pythonのクラスを辞書のようにして使う
http://blog.beanz-net.jp/happy_programming/2008/11/python-5.html
特殊メソッド名 - Dive Into Python 3 日本語版
http://diveintopython3-ja.rdy.jp/special-method-names.html

BASE.py
# coding: utf-8

class BASE(object):

    def __init__(self):
        pass

    def __setitem__(self, key, value):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> print(b.key1)
        value1

        '''
        self.__dict__[key] = value
        return (self.__dict__[key], value)

    def __getitem__(self, key):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> print(b['key2'])
        value2

        '''
        return self.__dict__[key]

    def __len__(self):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> len(b)
        2

        '''
        return len(self.__dict__)

    def __iter__(self):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> for i in b: print(i)
        ('key2', 'value2')
        ('key1', 'value1')

        '''
        return self.__dict__.iteritems()

    def __contains__(self, key):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> 'key' in b
        True

        '''
        if key in self.__dict__.keys(): return True
        else: return False

    def __str__(self):
        '''
        >>> b = BASE()
        >>> b['key3'] = 10.0 / 3
        >>> print(b.key3)
        3.33333333333
        >>> print(b['key3'])
        3.33333333333

        '''
        return str(self.__dict__)

    def __repr__(self):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> b['key3'] = 10.0 / 3
        >>> print(b)
        {'key3': 3.3333333333333335, 'key2': 'value2', 'key1': 'value1'}

        '''
        return repr(self.__dict__)

    def keys(self):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> b['key3'] = 10.0 / 3
        >>> b.keys()
        ['key3', 'key2', 'key1']

        '''
        return self.__dict__.keys()

    def values(self):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> b['key3'] = 10.0 / 3
        >>> b.values()
        [3.3333333333333335, 'value2', 'value1']

        '''
        return self.__dict__.values()

    def items(self):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> b['key3'] = 10.0 / 3
        >>> b.items()
        [('key3', 3.3333333333333335), ('key2', 'value2'), ('key1', 'value1')]

        '''
        return self.__dict__.items()

def usage():

    class Example(BASE):
        pass

    ex = Example()

    ex['key1'] = 'value1'
    ex.key2    = 'value2'
    ex.key3    = 10.0 / 3

    print('''\n### usage ### \n\n'''
          '''class Example(BASE):\n'''
          '''    pass\n'''
          '''\n'''
          '''ex = Example()\n'''
          '''ex['key1'] = 'value1'\n'''
          '''ex.key2    = 'value2'\n'''
          '''ex.key3    = 10.0 / 3\n'''
          )

    print('print(type(ex))\n')
    print('    =>  %s\n' % type(ex))

    print('print(ex)\n')
    print('    =>  %s\n' % ex)

    print('print(ex.key1)\n')
    print('    =>  %s\n' % ex.key1)

    print('''print(ex['key2'])\n''')
    print('    =>  %s\n' % ex['key2'])

    print('''print(ex['key3'])\n''')
    print('    =>  %s\n' % ex['key3'])

    print('print(len(ex))\n')
    print('    =>  %d\n' % len(ex))

    print('print(ex.keys())\n')
    print('    =>  %s\n' % ex.keys())

    print('print(ex.values())\n')
    print('    =>  %s\n' % ex.values())

    print('print(ex.items())\n')
    print('    =>  %s\n' % ex.items())

    print('print([ i for i in ex ])\n')
    print('    =>  %s\n' % [ i for i in ex ])

    print('''print('key1' in ex)\n''')
    print('    =>  %s\n' % ('key1' in ex))

    print('''print('key4' in ex)\n''')
    print('    => %s\n'  % ('key4' in ex))

if __name__ == '__main__' : usage()

sorted()でソートさせる

ソートするデーターは汎用基底クラス(BASE.py)を継承したオブジェクトに格納する
ソートには sorted() http://docs.python.jp/2/howto/sorting.html を利用し sorted() のkey パラメータに
lambda と operator モジュールの attrgetter()を指定した2パターンで出力させる。

example.py
# -*- coding: utf-8 -*-

from BASE import BASE
from operator import attrgetter

# 汎用基底クラスを継承して名簿クラス作成
class Persons(BASE):
    pass

# 汎用基底クラスを継承して成績データクラスの作成
class Data(BASE):
    def __init__(self, id, name, kokugo, eigo):
        self.id     = id
        self.name   = name
        self.kokugo = kokugo
        self.eigo   = eigo

# 成績データーリストを返す
def get_persons():
    '''
    >>> get_persons()
    [{'eigo': 10, 'id': '0004', 'kokugo': 20, 'name': 'C'},
     {'eigo': 40, 'id': '0001', 'kokugo': 10, 'name': 'A'},
     {'eigo': 30, 'id': '0002', 'kokugo': 40, 'name': 'D'},
     {'eigo': 20, 'id': '0003', 'kokugo': 30, 'name': 'B'}]
    ]
    '''
    # 名簿オブジェクト作成
    p = Persons()
    # 名簿オブジェクトに成績データオブジェクトを入れる
    p['0001'] = Data('0001', 'A', 10, 40)
    p['0003'] = Data('0003', 'B', 30, 20)
    p['0002'] = Data('0002', 'D', 40, 30)
    p['0004'] = Data('0004', 'C', 20, 10)
    persons   = p.values()
    return persons

# 出力時のデコレーション用
def output_decoration(func):
    def wrapper(*args,**kwargs):
        print('# sort_key: %(sort_key)s' % kwargs)
        print('+----+-----+------+------+')
        print('|%-4s|%-5s|%-6s|%-6s|' % ('id', 'name', 'kokugo', 'eigo'))
        print('+----+-----+------+------+')
        func(*args,**kwargs)
        print('+----+-----+------+------+')
    return wrapper

# sorted の keyパラメータに operator モジュールの attrgetter 関数 を指定したソート
@output_decoration
def output_use_operator(persons, sort_key):
    for person_data in sorted(persons, reverse=False, key=attrgetter(sort_key)):
        print('|%(id)4s|%(name)-5s|%(kokugo)6d|%(eigo)6d|' % person_data)

# sorted の keyパラメータに lambda を指定したソート
@output_decoration
def output_use_lambda(persons, sort_key):
    for person_data in sorted(persons, reverse=False, key=lambda x: x[sort_key]):
        print('|%(id)4s|%(name)-5s|%(kokugo)6d|%(eigo)6d|' % person_data)

if __name__ == '__main__' :

    # 名簿オブジェクト取得
    persons = get_persons()
    # 国語の点数をソートキーとして出力する (sortedのkeyパラメータは attrgetter 関数)
    print "\n# sort_parameter: operator.attrgetter"
    output_use_operator(persons, sort_key='kokugo')
    # 英語の点数をソートキーとして出力する (sortedのkeyパラメータは lambda)
    print "\n# sort_parameter: lambda"
    output_use_lambda(persons, sort_key='eigo')

結果

# sort_parameter: operator.attrgetter
# sort_key: kokugo
+----+-----+------+------+
|id  |name |kokugo|eigo  |
+----+-----+------+------+
|0001|A    |    10|    40|
|0004|C    |    20|    10|
|0003|B    |    30|    20|
|0002|D    |    40|    30|
+----+-----+------+------+

# sort_parameter: lambda
# sort_key: eigo
+----+-----+------+------+
|id  |name |kokugo|eigo  |
+----+-----+------+------+
|0004|C    |    20|    10|
|0003|B    |    30|    20|
|0002|D    |    40|    30|
|0001|A    |    10|    40|
+----+-----+------+------+
6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6