对具有保持在固定位置的特定值的列表进行排序

时间:2017-07-28 20:48:45

标签: python algorithm python-3.x sorting

我有一个字符串列表。我想只对符合特定条件的值进行排序。考虑这个列表

x

我只想对其中包含['foo','bar','testa','python','java','abc'] 的值进行排序。结果应如下所示

a

['foo','abc','bar','python','java','testa'] 元素会适当地更改位置,但其他元素会保留其原始位置。

我完全不知道如何实现这一点,所以我希望别人能做到。有人能告诉我怎么做吗?

5 个答案:

答案 0 :(得分:6)

y = sorted(w for w in x if 'a' in w)  # pick and sort only the elements with 'a'
x = [w if 'a' not in w else y.pop(0) for w in x]

最后一行留下没有'a'的单词,而'a'的单词从y列表中逐渐被选中(已经排序)

修改: @MartijnPieters解决方案表现更好,因为它使用迭代器,不会使用额外的内存来存储y

y = iter(sorted(w for w in x if 'a' in w))  # create iterator, don't use memory
x = [w if 'a' not in w else next(y) for w in x]  # yield from iter instead of popping from a list

由于看起来你需要这个算法来处理不同的条件,你可以把它放到一个方法中:

x = ['foo','bar','testa','python','java','abc']

def conditional_sort(ls, f):
    y = iter(sorted(w for w in ls if f(w)))
    return [w if not f(w) else next(y) for w in ls]

conditional_sort(x, lambda w: 'a' in w)

第一个参数是列表,第二个参数是一个接受单个参数并返回bool值的函数。

答案 1 :(得分:1)

使用a查找元素;标记位置并将它们拉出来。

orig = ['foo','bar','testa','python','java','abc']
just_a = [str for str in orig if `a` in str]
mark = [`a` in str for str in orig]

这给了我们

just_a = ['bar', 'testa', 'java', 'abc'] 
mark = [False, True, True, False, True, True]

排序just_a;我相信你能做到。现在,构建您的结果:在Truemark的位置,获取排序列表中的下一个项目;否则,采取原始元素。

result = []
for pos in range len(orig):
    if mark[pos]:
        result.append(sort_a.pop())
    else:
        result.append(orig[pos])

这可以用更少的代码完成。除此之外,最后一个循环可以通过列表理解来完成。此代码仅阐明了该过程。

答案 2 :(得分:0)

可能的方法是:

  1. 提取所有值中的'a'并记下其位置。
  2. 按字母顺序对值排序(请参阅this post)。
  3. 将已排序的值插入原始列表。

答案 3 :(得分:0)

这绝对可以简化,但这是一种方法

def custom_sort(lst):
    sorted_list = [x for x in lst if 'a' in x] # get list of everything with an a in it
    sorted_list.sort() # sort this of elements containing a
    final_list = [] # make empty list, we will fill this with what we need
    sorted_counter = 0 # need a counter to keep track of what element containing a have been accounted for below
    for x in lst: # loop over original list
        if 'a' in x: # if that element in our original list contains an a
            final_list.append(sorted_list[sorted_counter]) # then we will from our sorted list of elements with a
            sorted_counter += 1 # increment counter
        else: # otherwise
            final_list.append(x) # we add an element from our original list
    return final_list # return the custom sorted list

答案 4 :(得分:0)

我只会使用另外两个列表来跟踪带有'a'的单词索引并对单词进行排序:

Setting tail to: 40
40
40
1
The tail is: 30
30
30
2

可能不是很有效但它有效。