在列表列表中对值进行排序

zdm:

我有一份A长度清单m每个的清单都A包含来自的正数{1, 2, ..., n}以下是一个示例,其中m = 3n = 4

A = [[1, 1, 3], [1, 2], [1, 1, 2, 4]]

我是代表每个数字xA为一对(i, j),其中A[i][j] = x我想A按降序排列数字;以最低的第一个指数打破平局。也就是说,如果A[i1][j1] == A[i2][j2],则(i1, j1)(i2, j2)iff 之前出现i1 <= i2

在示例中,我想返回对:

(0, 0), (0, 1), (1, 0), (2, 0), (2, 1), (1, 1), (2, 2), (0, 2), (2, 3)

代表排序的数字

1, 1, 1, 1, 1, 2, 2, 3, 4

我所做的是一种朴素的方法,其工作方式如下:

  • 首先,我对中的所有列表进行排序A
  • 然后,我迭代其中的数字{1, 2, ..., n}和列表A并添加对。

码:

for i in range(m): 
    A[i].sort()
S = []
for x in range(1, n+1):
    for i in range(m):
        for j in range(len(A[i])):
            if A[i][j] == x:
                S.append((i, j))

我认为这种方法不好。我们可以做得更好吗?

cs95:

list.sort

您可以生成索引列表,然后调用list.sortkey

B = [(i, j) for i, x in enumerate(A) for j, _ in enumerate(x)]
B.sort(key=lambda ix: A[ix[0]][ix[1]])

print(B)
[(0, 0), (0, 1), (1, 0), (2, 0), (2, 1), (1, 1), (2, 2), (0, 2), (2, 3)]

请注意,在python-2.x上,它支持可迭代的函数拆包,您可以sort稍微简化一下调用:

B.sort(key=lambda (i, j): A[i][j])

sorted

这是上述版本的替代方法,并生成两个列表(一个在内存中,sorted然后继续使用,以返回另一个副本)。

B = sorted([
       (i, j) for i, x in enumerate(A) for j, _ in enumerate(x)
    ], 
    key=lambda ix: A[ix[0]][ix[1]]
)

print(B)
[(0, 0), (0, 1), (1, 0), (2, 0), (2, 1), (1, 1), (2, 2), (0, 2), (2, 3)]

性能

根据大众需求,添加一些时间和情节。

在此处输入图片说明

从图中可以看出,调用list.sort比效率更高sorted这是因为list.sort执行就地排序,因此创建具有该数据的副本不会浪费时间/空间sorted

功能

def cs1(A):
    B = [(i, j) for i, x in enumerate(A) for j, _ in enumerate(x)]
    B.sort(key=lambda ix: A[ix[0]][ix[1]]) 

    return B

def cs2(A):
    return sorted([
           (i, j) for i, x in enumerate(A) for j, _ in enumerate(x)
        ], 
        key=lambda ix: A[ix[0]][ix[1]]
    )

def rorydaulton(A):

    triplets = [(x, i, j) for i, row in enumerate(A) for j, x in enumerate(row)]
    pairs = [(i, j) for x, i, j in sorted(triplets)]

    return pairs

def jpp(A):
    def _create_array(data):
        lens = np.array([len(i) for i in data])
        mask = np.arange(lens.max()) < lens[:,None]
        out = np.full(mask.shape, max(map(max, data))+1, dtype=int)  # Pad with max_value + 1
        out[mask] = np.concatenate(data)
        return out

    def _apply_argsort(arr):
        return np.dstack(np.unravel_index(np.argsort(arr.ravel()), arr.shape))[0]

    return _apply_argsort(_create_array(A))[:sum(map(len, A))]

def agngazer(A):
    idx = np.argsort(np.fromiter(chain(*A), dtype=np.int))
    return np.array(
       tuple((i, j) for i, r in enumerate(A) for j, _ in enumerate(r))
    )[idx]

绩效基准代码

from timeit import timeit
from itertools import chain

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

res = pd.DataFrame(
       index=['cs1', 'cs2', 'rorydaulton', 'jpp', 'agngazer'],
       columns=[10, 50, 100, 500, 1000, 5000, 10000, 50000],
       dtype=float
)

for f in res.index: 
    for c in res.columns:
        l = [[1, 1, 3], [1, 2], [1, 1, 2, 4]] * c
        stmt = '{}(l)'.format(f)
        setp = 'from __main__ import l, {}'.format(f)
        res.at[f, c] = timeit(stmt, setp, number=30)

ax = res.div(res.min()).T.plot(loglog=True) 
ax.set_xlabel("N"); 
ax.set_ylabel("time (relative)");

plt.show();

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

对列表中的列表列表进行排序

如何根据列表中的相同设置值对列表列表进行排序?

在列表列表中对列表元素进行重新排序

按最小值对列表列表进行排序

在Python中按长度和值对列表列表进行排序

对字典/列表列表中的多个参数进行排序

根据特定列对Python中的列表列表进行排序

如何在Java中对列表列表进行排序?

如何在R中对列表列表进行排序?

在python中对字典列表列表进行排序

如何在 C# 中对列表列表进行排序?

Python对列表列表进行排序

无法对列表列表进行排序

对列表列表中的元素重新排序

根据在每个单独的列表中添加数字对列表列表进行排序

使用内部列表中的特定变量对列表列表进行排序

根据子列表中的字母数字字符串对列表列表进行自然排序?

通过对Lisp中的子列表列表进行排序来保留列表结构

如何对列表列表进行排序并删除空列表?

如何根据子列表的长度对列表列表进行排序

按内部列表的特定索引对列表列表进行排序

如何根据内部列表的长度对列表列表进行排序?

如何对嵌套列表中的值进行排序?

如何对列表中的字典值进行排序?

根据列表中的值对字典进行排序

Python在排序后对列表列表进行重新排序

按min属性值对类实例的元组列表列表进行排序

如何在过滤出某些值的同时对列表列表进行排序?

对列表中的列表进行排序