【问题标题】:Finding the highest version in my list of lists在我的列表中查找最高版本
【发布时间】:2019-08-03 04:35:26
【问题描述】:

我有一个列表列表:

['test', 'testlink', 1]
['test', 'testlink', 2]
['test ', 'testlink', 3]
['test ', 'testlink', 4]
['test 2', 'test2link', 1]
['test 2', 'test2link', 2]
['test 3', 'test3link', 1]
['test 3', 'test3link', 3]
['test 3', 'test3link', 4]

我想过滤列表以返回每个唯一第一个元素的第三个元素的最大值。

我想要的结果是:

['test ', 'testlink', 4]
['test 2', 'test2link', 2]
['test 3', 'test3link', 4]

我正在努力寻找一种方法来做到这一点。下面的代码块进入我的排序列表,但在那之后我被卡住了。

#create some dummy data
rows=[]
rows.append(["test","testlink",1])
rows.append(["test 2","test2link",1])
rows.append(["test 3","test3link",1])
rows.append(["test","testlink",2])
rows.append(["test","testlink",1])
rows.append(["test 2","test2link",1])
rows.append(["test 3","test3link",1])
rows.append(["test ","testlink",3])
rows.append(["test 3","test3link",3])
rows.append(["test ","testlink",4])
rows.append(["test 3","test3link",4])
rows.append(["test 2","test2link",2])
#filter out duplicates
newRows = []
for elem in rows:
    if elem not in newRows:
        newRows.append(elem)
rows = newRows
#sort the lists
rows = sorted(rows,key=lambda x: (x[0],x[2]))

感谢所有排序给出的答案都可以在我的 Ironpython 环境中工作

【问题讨论】:

  • 你根本不关心第二个元素吗?如果两个列表的第一个元素相同,但第二个元素不同,会发生什么?
  • 如果它们具有相同的第一个元素和不同的第三个元素,则默认情况下它们具有不同的第二个元素。抱歉,我的虚拟代码没有说明这一点。 :-)。重要的元素是第三个元素,因为它是当前版本。

标签: python list filtering ironpython


【解决方案1】:

你可以使用defaultdict:

from collections import defaultdict

l = [['test', 'testlink', 1],
     ['test', 'testlink', 2],
     ['test', 'testlink', 3],
     ['test', 'testlink', 4],
     ['test 2', 'test2link', 1],
     ['test 2', 'test2link', 2],
     ['test 3', 'test3link', 1],
     ['test 3', 'test3link', 3],
     ['test 3', 'test3link', 4]]

d = defaultdict(int)
for first, second, third in l:
    if d[(first, second)] < third:
       d[(first, second)] = third

要形成您想要使用下一行的格式的结果:

res = [[*key, value] for key, value in d.items()]

如果你不想导入defaultdict,你可以使用普通的:

d = {}
for first, second, third in l:
    item = d.get((first, second), None)
    if not item or item < third:
       d[(first, second)] = third

【讨论】:

  • 谢谢。我明白了,但这并不完全符合我的要求,因为返回的结果采用 [(first,second), third] 的形式。我认为 res=[[*key.... * 是一个错字,因为我在包含它时会出现语法错误。删除 * 得到结果,但前两个括号如图所示。
  • * 不是错字,是unpacking ;)
  • @PoorGolfer,我在发布答案之前验证了代码,它按预期工作。你能提供发生的错误吗?
  • 我认为这是我的python环境的限制。我正在使用基于 python 2.7 的 ironpython。我相信 *key 只是 Python 3。再次感谢。
  • @PoorGolfer,对于 python2 使用 res = [[key[0], key[1], value] for key, value in d.items()]
【解决方案2】:

使用itertools.groupby (doc) 的一种解决方案:

rows=[]
rows.append(["test","testlink",1])
rows.append(["test 2","test2link",1])
rows.append(["test 3","test3link",1])
rows.append(["test","testlink",2])
rows.append(["test","testlink",1])
rows.append(["test 2","test2link",1])
rows.append(["test 3","test3link",1])
rows.append(["test ","testlink",3])
rows.append(["test 3","test3link",3])
rows.append(["test ","testlink",4])
rows.append(["test 3","test3link",4])
rows.append(["test 2","test2link",2])

from itertools import groupby

out = []
for v, g in groupby(sorted(rows, key=lambda k: k[0].strip()), lambda k: k[0].strip()):
    item = max(g, key=lambda k: k[2])
    out.append(item)

from pprint import pprint
pprint(out)

打印:

[['test ', 'testlink', 4],
 ['test 2', 'test2link', 2],
 ['test 3', 'test3link', 4]]

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2021-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多