强制项目在列表的开头和结尾

时间:2018-12-27 16:19:13

标签: python list sorting

如何修改此列表,以使所有p's出现在开头,q's出现在结尾,并且中间的值按字母顺序排序?

l = ['f','g','p','a','p','c','b','q','z','n','d','t','q']

所以我想拥有:

['p','p','a','b','c','d','f','g','n','t','z','q','q']

8 个答案:

答案 0 :(得分:51)

您可以将sorted与以下key一起使用:

sorted(l, key = lambda s: (s!='p', s=='q', s))
['p', 'p', 'a', 'b', 'c', 'd', 'f', 'g', 'n', 't', 'z', 'q', 'q']

说明

为了更好地了解其工作方式,以下列表理解旨在在进行比较之前复制从lambda参数中定义的key函数返回的内容:

t = [(s!='p', s=='q', s) for s in pl]

print(t)
[(True, False, 'f'),
 (True, False, 'g'),
 (False, False, 'p'),
 (True, False, 'a'),
 (False, False, 'p'),
 (True, False, 'c'),
 (True, False, 'b'),
 (True, True, 'q'),
 (True, False, 'z'),
 (True, False, 'n'),
 (True, False, 'd'),
 (True, False, 't'),
 (True, True, 'q')]

这将是key,用于对列表中的项目进行排序,如documentation中所述:

  

key参数的值应该是一个函数,该函数接受单个参数并返回用于排序目的的键。

因此,考虑到False = 0True = 1,在对这个元组列表进行排序时,结果如下:

sorted(t)
[(False, False, 'p'),
 (False, False, 'p'),
 (True, False, 'a'),
 (True, False, 'b'),
 (True, False, 'c'),
 (True, False, 'd'),
 (True, False, 'f'),
 (True, False, 'g'),
 (True, False, 'n'),
 (True, False, 't'),
 (True, False, 'z'),
 (True, True, 'q'),
 (True, True, 'q')]

答案 1 :(得分:19)

一个想法是使用具有自定义功能的优先级字典。如果您希望包括其他条件,则可以自然扩展。

L = ['f','g','p','a','p','c','b','q','z','n','d','t','q']

def sort_func(x):
    priority = {'p': 0, 'q': 2}
    return priority.get(x, 1), x

res = sorted(L, key=sort_func)

print(res)

['p', 'p', 'a', 'b', 'c', 'd', 'f', 'g', 'n', 't', 'z', 'q', 'q']

答案 2 :(得分:14)

使用sorted中的 <ComboBox.ItemContainerStyle> <Style TargetType="ComboBoxItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <TextBlock Text="{Binding}" Focusable="False" /> </ControlTemplate> </Setter.Value> </Setter> </Style> </ComboBox.ItemContainerStyle> 参数:

key

输出

l = ['f','g','p','a','p','c','b','q','z','n','d','t','q']

def key(c):
    if c == 'q':
        return (2, c)
    elif c == 'p':
        return (0, c)
    return (1, c)


result = sorted(l, key=key)
print(result)

答案 3 :(得分:7)

只需定义适当的键功能:

>>> def _key(x):
...     if x == 'p':
...         return -1
...     elif x == 'q':
...         return float('inf')
...     else:
...         return ord(x)
...
>>> l = ['f','g','p','a','p','c','b','q','z','n','d','t','q']
>>> sorted(l, key=_key)
['p', 'p', 'a', 'b', 'c', 'd', 'f', 'g', 'n', 't', 'z', 'q', 'q']

请注意,每个字符都映射为> = 0的整数,因此我们只能依靠ord,并且由于-1总是小于ord返回的任何内容,因此我们可以将其用于p,对于q,我们可以使用无穷大,因此它总是大于ord返回的值。

答案 4 :(得分:4)

您可以找到所有pq元素,过滤原始列表,然后排序:

l = ['f','g','p','a','p','c','b','q','z','n','d','t','q']
_ps, _qs = [i for i in l if i == 'p'], [i for i in l if i == 'q']
new_l = _ps+sorted(filter(lambda x:x not in {'q', 'p'}, l))+_qs

输出:

['p', 'p', 'a', 'b', 'c', 'd', 'f', 'g', 'n', 't', 'z', 'q', 'q']

答案 5 :(得分:2)

您还可以将您的开头,中间和结尾存储在collections.defaultdict()中,然后只需在末尾添加所有三个列表:

from collections import defaultdict

l = ["f", "g", "p", "a", "p", "c", "b", "q", "z", "n", "d", "t", "q"]

keys = {"p": "front", "q": "end"}

d = defaultdict(list)
for item in l:
    d[keys.get(item, "middle")].append(item)

print(d["front"] + sorted(d["middle"]) + d["end"])
# ['p', 'p', 'a', 'b', 'c', 'd', 'f', 'g', 'n', 't', 'z', 'q', 'q']

答案 6 :(得分:1)

此问题的解决方案是:

  1. 首先找到列表中的所有p和q元素。
  2. 过滤原始列表。
  3. 然后,最后对列表进行排序。

<style>
@font-face {
  font-family: 'ABeeZee';
  font-style: normal;
  font-weight: 400;
  src: local('ABeeZee Regular'), local('ABeeZee-Regular'), url(data:font/woff2;base64,...)
}
</style>

答案 7 :(得分:0)

您可以使用以下lambda函数作为sorted()中的键:

l1 = sorted(l, key=lambda x: ((x == 'q') - (x == 'p'), x))

print(l1)
# ['p', 'p', 'a', 'b', 'c', 'd', 'f', 'g', 'n', 't', 'z', 'q', 'q']

该函数生成以下比较键:

func = lambda x: ((x == 'q') - (x == 'p'), x)

for i in l1:
    print(func(i))

输出:

(-1, 'p')
(-1, 'p')
(0, 'a')
(0, 'b')
...
(0, 't')
(0, 'z')
(1, 'q')
(1, 'q')