将python中的列表与条件组合

时间:2017-02-15 09:36:35

标签: python list

我有两个列表,如下所示:

  user_list = ['oshamir','oshamir','oshamir','ctmuser','ctmuser','root','root','root']

  num_list =  ['400','700','600','300','500','1000','400','2000']

我想将一个列表与每个用户最大数量的条件组合起来,最后我会得到这个列表

[['oshamir','700'],['ctmuser','500'],['root','2000']]

有什么建议吗?

TNX

3 个答案:

答案 0 :(得分:6)

您可以使用zip将列表配对,然后按用户分组对,并从每个组中选择一个具有最大值的列表:

>>> from itertools import groupby
>>> user_list = ['oshamir','oshamir','oshamir','ctmuser','ctmuser','root','root','root']
>>> num_list =  ['400','700','600','300','500','1000','400','2000']
>>> [max(g, key=lambda x: int(x[1])) for _, g in groupby(zip(user_list, num_list), lambda x: x[0])]
[('oshamir', '700'), ('ctmuser', '500'), ('root', '2000')]

在上面zip中返回(user, num)元组的可迭代:

>>> pairs = list(zip(user_list, num_list))
>>> pairs
[('oshamir', '400'), ('oshamir', '700'), ('oshamir', '600'), ('ctmuser', '300'), ('ctmuser', '500'), ('root', '1000'), ('root', '400'), ('root', '2000')]

然后groupby用于根据每个元组中的第一项对项目进行分组:

>>> groups = [list(g) for _, g in groupby(pairs, lambda x: x[0])]
>>> groups
[[('oshamir', '400'), ('oshamir', '700'), ('oshamir', '600')], [('ctmuser', '300'), ('ctmuser', '500')], [('root', '1000'), ('root', '400'), ('root', '2000')]]

最后,使用key函数max来选择具有最大值的对。请注意,num_list上的项目是字符串,因此需要将其转换为数字,以便我们选择'2000'而不是'400'

>>> [max(g, key=lambda x: int(x[1])) for g in groups]
[('oshamir', '700'), ('ctmuser', '500'), ('root', '2000')]

答案 1 :(得分:0)

如果订单很重要,您可以使用OrderedDict,否则正常的dict会使用>>> d = OrderedDict() >>> for user, num in zip(user_list, num_list): ... d[user] = max(d.get(user, float('-inf')), int(num)) ... >>> [[k,v] for k,v in d.items()] [['oshamir', 700], ['ctmuser', 500], ['root', 2000]] >>> 。但基本上,使用一个pass来进行从user到num的映射,每次都保持较大的值。然后,另一个传递来获得你想要的数据结构。

cat mail.log | grep "postfix/smtp" | grep -P 'status=(?!sent)' | 
sed "s/^.*: \(.\+\):.* to=<\(.\+\)>.* status=\([^ ]\+\) (\(.*\))$/[\1] <\2> \3: \4/" |
sort | uniq

答案 2 :(得分:0)

您需要的排序需要数字而不是字符串。将数字排序为字符串时会返回不同的结果。

res = list(zip(user_list, map(int, num_list)))  # [('oshamir', 400), ('oshamir', 700), ('oshamir', 600), ('ctmuser', 300), ('ctmuser', 500), ('root', 1000), ('root', 400), ('root', 2000)]
res.sort(key=lambda x: (x[0], x[1]))            # [('ctmuser', 300), ('ctmuser', 500), ('oshamir', 400), ('oshamir', 600), ('oshamir', 700), ('root', 400), ('root', 1000), ('root', 2000)]
final = {k:str(v) for k,v in res}               # {'ctmuser': '500', 'root': '2000', 'oshamir': '700'}

所以我会转换为数字,排序并获得最大值,最后切换回字符串。

如果您明确要求列表列表作为输出,您可以在顶部添加列表理解,如下所示:

final = [[a, b] for a, b in final.items()]      # [['ctmuser', '500'], ['root', '2000'], ['oshamir', '700']]