若有底下這種資料,是個串列,含有多個字典。
data = [
{'age': 31, 'city': 'taipei', 'name': 'amy'},
{'age': 71, 'city': 'tokyo', 'name': 'john'},
{'age': 16, 'city': 'london', 'name': 'zoe'},
{'age': 16, 'city': 'rio', 'name': 'cathy'},
{'age': 48, 'city': 'frankfurt', 'name': 'david'}]
那麼,呼叫內建函式sorted時,能以參數key傳入lambda,指定要根據哪個元素進行排序。
根據age年齡排序:
print(sorted(data, key=lambda x: x['age']))
先排age年齡、再排name名字:
print(sorted(data, key=lambda x: (x['age'], x['name'])))
不過也能運用operator.itemgetter取出想排序的元素,而且聽說速度更快,試試看吧。
import random
import string
from operator import itemgetter
先寫個會亂數產生字串的函式,預設回傳長度介於3到10的字串,都是小寫字母。
def random_str(size_lower=3, size_upper=10):
size = random.randint(size_lower, size_upper)
return ''.join(random.choice(string.ascii_lowercase) for _ in range(size))
然後撰寫亂數產生資料的函式,參數size代表想要幾個元素(字典)。
def random_data(size):
result = []
for _ in range(size):
d = {}
d['age'] = random.randint(1, 99)
d['name'] = random_str()
d['city'] = random_str()
result.append(d)
return result
產生資料,此處寫著DATA_SIZE為1000,之後測試時可修改。
DATA_SIZE = 1000
data = random_data(DATA_SIZE)
受測函式一,使用lambda,分別進行幾次排序。
def test_lambda():
data0 = sorted(data, key=lambda x: x['age'])
data1 = sorted(data, key=lambda x: x['name'])
data2 = sorted(data, key=lambda x: x['city'])
data3 = sorted(data, key=lambda x: (x['age'], x['name']))
data4 = sorted(data, key=lambda x: (x['age'], x['city']))
受測函式二,使用itemgetter,分別進行幾次排序。
def test_itemgetter():
data0 = sorted(data, key=itemgetter('age'))
data1 = sorted(data, key=itemgetter('name'))
data2 = sorted(data, key=itemgetter('city'))
data3 = sorted(data, key=itemgetter('age', 'name'))
data4 = sorted(data, key=itemgetter('age', 'city'))
測量所需時間,此處TEST_COUNT為100,代表跑100次,可修改。
if __name__ == '__main__':
from timeit import Timer
TEST_COUNT = 100
t_lambda = Timer('test_lambda()', 'from __main__ import test_lambda')
print('lambda: ', t_lambda.timeit(TEST_COUNT))
t_itemgetter = Timer('test_itemgetter()', 'from __main__ import test_itemgetter')
print('itemgetter: ', t_itemgetter.timeit(TEST_COUNT))
來測試看看吧,環境是WinXP、Cygwin、Python 2.7.10:
DATA_SIZE 1000,TEST_COUNT 100
lambda 0.734375
itemgetter 0.71875
DATA_SIZE 1000,TEST_COUNT 1000
lambda 7.46875
itemgetter 6.25
DATA_SIZE 1000,TEST_COUNT 10000
lambda 77.421875
itemgetter 62.921875
加大DATA_SIZE試試看吧:
DATA_SIZE 10000,TEST_COUNT 100
lambda 12.203125
itemgetter 10.953125
DATA_SIZE 10000,TEST_COUNT 1000
lambda 123.90625
itemgetter 110.375
綜合而言,itemgetter比較快,所需時間大約是lambda的80%~97%。
我也用Python 3.4.3測試,情況差不多,不過實際測得的所需時間,都比Python 2.7.10版的時候要久,也就是說Python 3比2慢啦。
2015/06/19
Python筆記:operator.itemgetter
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment