我有两个列表,如下所示:
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
答案 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']]