2

我有一个字符串列表和一个排列。我正在尝试将排列应用于列表,但我正在尝试保持我的代码简洁明了。目前我有一个可行的解决方案,它看起来像这样:

mylist = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
permutation = [5,2,6,3,7,9,1,4,8]

mynewlist = ['']*9
for i in range(9):
    mynewlist[permutation[i]-1] = mylist[i]

print mynewlist

我不喜欢它的是我必须先将列表初始化为一个空列表,然后以一种奇怪的方式循环它。我只是想知道是否有人可以想出一种更简洁的方式来写这个,也许使用列表理解?还是通过应用地图?

仅供参考 - 上述结果是:

['g', 'b', 'd', 'h', 'a', 'c', 'e', 'i', 'f']
4

4 回答 4

3

您的算法,但更清洁:

mynewlist = mylist[:]
for pos, elem in zip(permutation, mylist):
    mynewlist[pos - 1] = elem
于 2013-04-18T14:18:31.773 回答
1

可以使用sorted()

sorted(mylist, key=lambda v, i=iter(permutation): next(i))

这输出:

>>> sorted(mylist, key=lambda v, i=iter(permutation): next(i))
['g', 'b', 'd', 'h', 'a', 'c', 'e', 'i', 'f']

mylist根据从permutation列表中获取的索引对输入进行排序;该key函数在排序之前按顺序为输入序列中的每个元素调用一次。

不过,这并不能与您的版本相比;你有一个 O(n) 算法,这需要 O(n lg n)。

于 2013-04-18T14:05:58.437 回答
0

只是一个疯狂的想法,但如何...

>>> mylist = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
>>> permutation = [5,2,6,3,7,9,1,4,8]
>>> {permutation[i]: v for i, v in enumerate(mylist)}.values()
['g', 'b', 'd', 'h', 'a', 'c', 'e', 'i', 'f']

...利用字典按散列值排序的事实,整数散列到它们自己的值。

我认为这是一个 O(n) 算法。

于 2013-04-18T14:28:53.363 回答
0

这是我的尝试:

mynewlist = [list_item for p, list_item in sorted(zip(permutation, mylist))]

结果是:

['g', 'b', 'd', 'h', 'a', 'c', 'e', 'i', 'f']

讨论

让我们从右边开始。该zip()函数将两个列表耦合在一起:

>>> zip(permutation, mylist)
[(5, 'a'), (2, 'b'), (6, 'c'), (3, 'd'), (7, 'e'), (9, 'f'), (1, 'g'), (4, 'h'), (8, 'i')]

然后我们可以对zip()函数的结果进行排序,这将产生一个按排列索引排序的元组列表:

>>> sorted(zip(permutation, mylist))
[(1, 'g'), (2, 'b'), (3, 'd'), (4, 'h'), (5, 'a'), (6, 'c'), (7, 'e'), (8, 'i'), (9, 'f')]

这几乎就是我们想要的:字符是有序的。下一步是消除排列索引,只留下字符。这就是我上面提出的最终形式。

于 2013-04-18T14:41:51.600 回答