1.13 通过æŸ�ä¸ªå…³é”®å—æŽ’åº�一个å—典列表¶
问题¶
ä½ æœ‰ä¸€ä¸ªå—å…¸åˆ—è¡¨ï¼Œä½ æƒ³æ ¹æ�®æŸ�个或æŸ�å‡ ä¸ªå—兏嗿®µæ�¥æŽ’åº�这个列表。
解决方案¶
通过使用 operator 模å�—çš„ itemgetter 函数,å�¯ä»¥é�žå¸¸å®¹æ˜“的排åº�è¿™æ ·çš„æ•°æ�®ç»“构。
å�‡è®¾ä½ 从数æ�®åº“䏿£€ç´¢å‡ºæ�¥ç½‘站会员信æ�¯åˆ—表,并且以下列的数æ�®ç»“构返回:
rows = [
{'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
{'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
{'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
]
æ ¹æ�®ä»»æ„�çš„å—兏嗿®µæ�¥æŽ’åº�输入结果行是很容易实现的,代ç �示例:
from operator import itemgetter
rows_by_fname = sorted(rows, key=itemgetter('fname'))
rows_by_uid = sorted(rows, key=itemgetter('uid'))
print(rows_by_fname)
print(rows_by_uid)
代ç �的输出如下:
[{'fname': 'Big', 'uid': 1004, 'lname': 'Jones'},
{'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'},
{'fname': 'David', 'uid': 1002, 'lname': 'Beazley'},
{'fname': 'John', 'uid': 1001, 'lname': 'Cleese'}]
[{'fname': 'John', 'uid': 1001, 'lname': 'Cleese'},
{'fname': 'David', 'uid': 1002, 'lname': 'Beazley'},
{'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'},
{'fname': 'Big', 'uid': 1004, 'lname': 'Jones'}]
itemgetter() 函数也支æŒ�多个 keys,比如下é�¢çš„代ç �
rows_by_lfname = sorted(rows, key=itemgetter('lname','fname'))
print(rows_by_lfname)
会产生如下的输出:
[{'fname': 'David', 'uid': 1002, 'lname': 'Beazley'},
{'fname': 'John', 'uid': 1001, 'lname': 'Cleese'},
{'fname': 'Big', 'uid': 1004, 'lname': 'Jones'},
{'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'}]
讨论¶
在上é�¢ä¾‹å�ä¸ï¼Œ rows è¢«ä¼ é€’ç»™æŽ¥å�—一个关键å—å�‚æ•°çš„ sorted() 内置函数。
这个å�‚数是 callable 类型,并且从 rows 䏿ޥå�—一个å�•ä¸€å…ƒç´ ï¼Œç„¶å�Žè¿”回被用æ�¥æŽ’åº�的值。
itemgetter() 函数就是负责创建这个 callable 对象的。
operator.itemgetter() 函数有一个被 rows ä¸çš„记录用æ�¥æŸ¥æ‰¾å€¼çš„索引å�‚数。å�¯ä»¥æ˜¯ä¸€ä¸ªå—典键å��称,
ä¸€ä¸ªæ•´å½¢å€¼æˆ–è€…ä»»ä½•èƒ½å¤Ÿä¼ å…¥ä¸€ä¸ªå¯¹è±¡çš„ __getitem__() 方法的值。
å¦‚æžœä½ ä¼ å…¥å¤šä¸ªç´¢å¼•å�‚æ•°ç»™ itemgetter() ,它生æˆ�çš„ callable 对象会返回一个包å�«æ‰€æœ‰å…ƒç´ 值的元组,
并且 sorted() å‡½æ•°ä¼šæ ¹æ�®è¿™ä¸ªå…ƒç»„ä¸å…ƒç´ 顺åº�去排åº�。
ä½†ä½ æƒ³è¦�å�Œæ—¶åœ¨å‡ ä¸ªå—æ®µä¸Šé�¢è¿›è¡ŒæŽ’åº�(比如通过姓和å��æ�¥æŽ’åº�,也就是例å�ä¸çš„é‚£æ ·ï¼‰çš„æ—¶å€™è¿™ç§�方法是很有用的。
itemgetter() 有时候也�以用 lambda 表达�代替,比如:
rows_by_fname = sorted(rows, key=lambda r: r['fname'])
rows_by_lfname = sorted(rows, key=lambda r: (r['lname'],r['fname']))
è¿™ç§�方案也ä¸�错。但是,使用 itemgetter() æ–¹å¼�会è¿�行的ç¨�å¾®å¿«ç‚¹ã€‚å› æ¤ï¼Œå¦‚æžœä½ å¯¹æ€§èƒ½è¦�求比较高的è¯�就使用 itemgetter() æ–¹å¼�。
最å�Žï¼Œä¸�è¦�忘了这节ä¸å±•示的技术也å�Œæ ·é€‚用于 min() å’Œ max() ç‰å‡½æ•°ã€‚比如:
>>> min(rows, key=itemgetter('uid'))
{'fname': 'John', 'lname': 'Cleese', 'uid': 1001}
>>> max(rows, key=itemgetter('uid'))
{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
>>>