按两个不同键

时间:2016-01-29 15:15:55

标签: algorithm sorting iteration sublist

我有一个算法包含以下情况;我想知道是否有可能取得一些进展(我不认为这是可能的,但我可能错了)。

我有一个objets列表L。我有两个不同的(和独立的)键来对它们进行排序:mykey1mykey2。实际上,我可以在算法开始时以两种方式对列表进行排序,但没有显着的成本;因此,我有两个清单:

A = sorted(L, key=mykey1)
B = sorted(L, key=mykey2)

(Python语法,但我认为任何人都可以理解)。只要复杂性仍然低于O( n log n ),我就可以在这个阶段做更多的事情(初始化新变量)。

我需要提取 A的许多子列表;而不是实际复制子列表,我想在我的算法的主循环期间使用索引(开始和结束),原因很明显。

现在,对于A的任意子列表(两个索引都知道),是否有一些棘手的方法来根据B中相应顺序(相同对象)的相应顺序迭代其对象?

这是一个快速而又肮脏的例子:

L = [(7,2), (4,3), (5,9), (1,8)]
mykey1 = lambda e: e[0]
mykey2 = lambda e: e[1]
A = sorted(L, key=mykey1) # A = [(1,8), (4,3), (5,9), (7,2)]
B = sorted(L, key=mykey2) # B = [(7,2), (4,3), (1,8), (5,9)]

在处理由A[0:2] [(1,8), (4,3)]构成的子列表时,有一些棘手的方法来迭代[(4,3), (1,8)](因为对象(4,3)来自对象{{ 1}}根据键(1,8)。为了达到这个目的,我想避免迭代任何其他对象而不是实际属于mykey2的对象?

我可以通过迭代整个A[0:2]并检查对象是否在子列表中来完成复杂度O( n )(通过添加一些字段不难实现)在B)给出其位置的对象;我可以做得更好吗?

2 个答案:

答案 0 :(得分:0)

自从我使用Python以来已经很长时间了,但不会像这样工作吗?

C = sorted(A[0:2], key=mykey2)

然后在将“B”排序/键应用于A子列表以生成它之后迭代C,或者您可以改为减去列表

C = B - A[2:2]

如果您的子列表可以递增生成,这可能是一种生成它们的简单方法,已经按B排序顺序。不是从A子列表开始并尝试按B顺序迭代它们,而是从B开始并从B开始并通过取消A顺序中的项目来生成子列表。

或者我在这里遗漏了一些东西。这似乎太简单了。

答案 1 :(得分:0)

I would suggest the next code snippet:

    L = [(7,2), (4,3), (5,9), (1,8)]
    mykey1 = lambda e: e[0]
    mykey2 = lambda e: e[1]
    A = sorted(L, key=mykey1)
    C = [sorted(_, key=mykey2) for _ in (A[0:_] for _ in (_ for _ in range(1, len(A) + 1)))]

C will be a list containing the sub-lists:
[[(1, 8)],
 [(4, 3), (1, 8)],
 [(4, 3), (1, 8), (5, 9)],
 [(7, 2), (4, 3), (1, 8), (5, 9)]]

Or, if we want to make C a [generator][1] (instead of a list); for lists we are keeping all elements in memory (performance issue) :

    C = (sorted(_, key=mykey2) for _ in (A[0:_] for _ in (_ for _ in range(1, len(A) + 1))))

Hope it helps.