我如何重新排列列表?

给定一个大小为 n的任意数组,我想根据数组的离散索引重新组织数组的元素。

Python 例子:

# Unique array of size n
[ "a", "b", "c", "d", "e", ... <n> ]


# Indices of array
[ 0, 1, 2, 3, 4, ... <index_of_n> ]


# Desired re-organization function 'indexMove'
indexMove(
[ "a", "b", "c", "d", "e", ... <n> ],
[ <index_of_n>, 4, 0, 2, 3, ... 1 ]
)


# Desired output from indexMove operation
[ <n>, "e", "a", "c", "d", ... "b" ]

执行此操作的最快方法是什么(实现最小的时间复杂度) ?

213145 次浏览

你可以这样做

mylist = ['a', 'b', 'c', 'd', 'e']
myorder = [3, 2, 0, 1, 4]
mylist = [mylist[i] for i in myorder]
print(mylist)         # prints: ['d', 'c', 'a', 'b', 'e']
>>> import random
>>> x = [1,2,3,4,5]
>>> random.shuffle(x)
>>> x
[5, 2, 4, 3, 1]
>>> a = [1, 2, 3]
>>> a[0], a[2] = a[2], a[0]
>>> a
[3, 2, 1]
>>> a=["a","b","c","d","e"]
>>> a[0],a[3] = a[3],a[0]
>>> a
['d', 'b', 'c', 'a', 'e']

最后的顺序是否由索引列表定义?

>>> items = [1, None, "chicken", int]
>>> order = [3, 0, 1, 2]


>>> ordered_list = [items[i] for i in order]
>>> ordered_list
[<type 'int'>, 1, None, 'chicken']

编辑: 嗯。 AJ 更快... 如何在 python 中重新排序列表?

newList = [oldList[3]]
newList.extend(oldList[:3])
newList.extend(oldList[4:])

您可以为 list.sort()提供自己的排序函数:

Sort ()方法使用可选参数来控制比较。

  • Cmp 指定了两个参数(列表项)的自定义比较函数,根据第一个参数是否被认为小于、等于或大于第二个参数: cmp=lambda x,y: cmp(x.lower(), y.lower()),它应该返回一个负数、零或正数。默认值是 None

  • Key 指定一个只有一个参数的函数,该函数用于从每个列表元素中提取比较键: key=str.lower。默认值是 None

  • Return 是一个布尔值。如果设置为 True,则对列表元素进行排序,就好像每个比较都是相反的。

一般来说,键和反向转换过程要比指定等效的 cmp 函数快得多。这是因为每个列表元素多次调用 cmp,而键和反向只触摸每个元素一次。

根据我对您的问题的理解,您似乎想要在 list上应用您指定的排列。这是通过指定另一个 list(我们称之为 p)来完成的,该 list保存应该出现在置换的 list中的原始 list元素的索引。然后使用 p创建一个新的 list,只需将 p中每个位置的元素替换为其索引位于该位置的元素。

def apply_permutation(lst, p):
return [lst[x] for x in p]


arr=list("abcde")
new_order=[3,2,0,1,4]


print apply_permutation(arr,new_order)

这个打印 ['d', 'c', 'a', 'b', 'e']

这实际上创建了一个新的 list,但是可以对它进行微不足道的修改以排列原来的“ in place”。

还有一件事情可以考虑,那就是黑暗所指出的另一种解释

Python 2.7中的代码

主要有:

  1. 按价值重新订购-已经解决 AJ 以上
  2. 按索引重新排序

    mylist = ['a', 'b', 'c', 'd', 'e']
    myorder = [3, 2, 0, 1, 4]
    
    
    mylist = sorted(zip(mylist, myorder), key=lambda x: x[1])
    print [item[0] for item in mylist]
    

This will print ['c', 'd', 'b', 'a', 'e']

这就是我在偶然发现这个问题时使用的方法。

def order(list_item, i): # reorder at index i
order_at = list_item.index(i)
ordered_list = list_item[order_at:] + list_item[:order_at]
return ordered_list

小写字母

order(string.ascii_lowercase, 'h'):
>>> 'hijklmnopqrstuvwxyzabcdefg'

它只是将列表转移到指定的索引

如果你使用 numpy,有一个简单的方法:

items = np.array(["a","b","c","d"])
indices = np.arange(items.shape[0])
np.random.shuffle(indices)
print(indices)
print(items[indices])

此代码返回:

[1 3 2 0]
['b' 'd' 'c' 'a']

如果你不那么在意效率,你可以依赖 numpy 的数组索引来使它更优雅:

a = ['123', 'abc', 456]
order = [2, 0, 1]
a2 = list( np.array(a, dtype=object)[order] )