我有很多代码在对嵌套元组的列表进行排序上,因此大部分的运行时间都花在了排序上。 ALTER PROCEDURE [dbo].[SelectItem]
@identifier VARCHAR(200)
AS
BEGIN
SELECT
tb_Items_Master.item_auto_code AS 'Item Code',
tb_Items_Master.item_name_en AS 'Item Name',
MIN(tb_Quantity_Expire.expity_date) AS 'Expiry',
SUM(tb_Quantity_Expire.quantity) AS 'Stock',
tb_Items_Master.price AS 'Price'
FROM
(tb_Items_Master
INNER JOIN
tb_Quantity_Expire ON tb_Items_Master.item_auto_code = tb_Quantity_Expire.item_auto_code
LEFT JOIN
tb_Items_Codes ON tb_Items_Master.item_auto_code = tb_Items_Codes.item_auto_code)
WHERE
tb_Items_Codes.item_code = @identifier
OR tb_Items_Master.item_name_en LIKE '%'+@identifier+'%'
OR tb_Items_Master.item_name_2 LIKE '%'+@identifier+'%'
-- I'm calling it in the following line
OR tb_Items_Master.item_auto_code = SELECT dbo.TryConvertInt(@identifier)
GROUP BY
tb_Items_Master.item_auto_code, tb_Items_Master.item_name_en,
tb_Items_Master.price;
END
加快了简单排序的速度,但是似乎无法弄清楚其实现对嵌套元组n项进行排序的实现,例如,operator.itemgetter
方法有效。
以下示例数据;
list.sort(key = lambda x: x[1][n])
如果我想按每个元组的第二个项目(在这种情况下为元组)排序;
import random
v1 = random.sample(range(1, 100), 10)
v2 = random.sample(range(1, 100), 10)
v3 = random.sample(range(1, 100), 10)
v4 = random.sample(range(1, 100), 10)
out = zip(v1, zip(v2, v3, v4))
[(18, (68, 11, 71)),
(72, (24, 3, 79)),
(2, (1, 84, 69)),
(24, (94, 79, 17)),
(19, (67, 76, 19)),
(44, (79, 12, 34)),
(42, (11, 33, 92)),
(90, (18, 52, 47)),
(65, (73, 59, 70)),
(95, (74, 85, 60))]
如果我想按每个元组的第二个元素(在本例中为一个元组)排序,并且我可以使用该第二个元素;
import operator
out.sort(key = operator.itemgetter(1))
[(2, (1, 84, 69)),
(42, (11, 33, 92)),
(90, (18, 52, 47)),
(72, (24, 3, 79)),
(19, (67, 76, 19)),
(18, (68, 11, 71)),
(65, (73, 59, 70)),
(95, (74, 85, 60)),
(44, (79, 12, 34)),
(24, (94, 79, 17))]
可以使用out.sort(key = lambda x: x[1][1])
[(72, (24, 3, 79)),
(18, (68, 11, 71)),
(44, (79, 12, 34)),
(42, (11, 33, 92)),
(90, (18, 52, 47)),
(65, (73, 59, 70)),
(19, (67, 76, 19)),
(24, (94, 79, 17)),
(2, (1, 84, 69)),
(95, (74, 85, 60))]
完成吗?谢谢。
答案 0 :(得分:2)
AFAIK,itemgetter
没有提供类似的模式。但是,您可以使用functools.partial
和reduce
来定义自己的名称:
>>> from functools import *
>>> deep_get = lambda *indices: partial(reduce, lambda x, i: x[i], indices)
>>> deep_get(1, 1)(out[0])
89
>>> sorted(out, key=deep_get(1, 1))
[(27, (56, 12, 88)),
(71, (9, 22, 25)),
(54, (35, 24, 93)),
(98, (44, 31, 48)),
(55, (37, 55, 44)),
(65, (93, 58, 81)),
(13, (25, 68, 78)),
(14, (96, 70, 38)),
(66, (50, 86, 15)),
(33, (52, 89, 83))]
请注意,虽然这比您的lambda
慢,但是对于不同级别的嵌套,它可能更具通用性。如果只是为了提高速度,您应该将lambda
替换为一个“适当的”函数def get(x): return x[1][1]
,这似乎和itemgetter
一样快(在我的系统上,对{{1}进行排序} out
(一个级别)或itemgetter
用1.3µs,def get
用1.7µs,lambda
用3µs)。
deep_get