如何比较数字子列表中的第一项,如果重复,比较第二项并选择第二项最小的子列表?
Posted
技术标签:
【中文标题】如何比较数字子列表中的第一项,如果重复,比较第二项并选择第二项最小的子列表?【英文标题】:How to compare first item in sublist of numbers, if repeated, compare the second item and pick the sublist with the smallest second item? 【发布时间】:2020-10-24 22:51:46 【问题描述】:我有一个带有数字的列表(LIST_long),我需要编写一个列表(LIST_short),其中包含每个第一项(氨基酸的序列号)只有一个具有最小第二项(距离)的子列表:
LIST_long = [['1', '50.9'], ['1', '9.0'], ['1', '10.2'], ['1', '2.0'], ['2', '50.1'], ['2', '8.8'],...]
LIST_short = [['1', '2.0'], ['2', '8.8'],...]
我在 Python 3.6 中编写了这样的代码:
import itertools
LIST_long = [['1', '50.9'], ['1', '9.0'], ['1', '10.2'], ['1', '2.0'], ['2', '50.1'], ['2', '8.8'],...]
LIST_short = []
LIST_long = sorted(LIST_long, key=lambda x:(x[0], x[1]))
for x, y in itertools.groupby(LIST_long, lambda x: x[0]):
LIST_short.append(list(y)[0])
print(LIST_short)
输出:
LIST_short = [['1', '10.2'], ['2', '50.1'],...]
而不是:
LIST_short = [['1', '2.0'], ['2', '8.8'], ...]
但是以这种方式附加['1', '10.2']
而不是['1', '2.0']
,因为据我了解,不是第二项的编号而是逐位比较,1在2之前; 5 之前 8 等等....
我将非常感谢有关此问题的帮助。 期待建议。
【问题讨论】:
【参考方案1】:您可以使用字典来获取结果,将子列表的第一项存储为字典的键,并对应地添加第二项作为列表中的值,然后获取列表的最小值,您就得到了需要的结果。
LIST_long = [['1', '50.9'], ['1', '9.0'], ['1', '10.2'], ['1', '2.0'], ['2', '50.1'], ['2', '8.8']]
from collections import defaultdict as dd
x = dd(list)
for i in LIST_long:
x[i[0]]+=[float(i[1])]
LIST_sort = []
for k, v in x.items():
LIST_sort.append([k, str(min(v))])
print(LIST_sort)
输出
[['1', '2.0'], ['2', '8.8']]
【讨论】:
谢谢@sahasrara62 你的问题也很好解决【参考方案2】:您的代码完美运行,您只需将x[1]
更改为float(x[1])
:
import itertools
LIST_long = [['1', '50.9'], ['1', '9.0'], ['1', '10.2'], ['1', '2.0'], ['2', '50.1'], ['2', '8.8'],...]
LIST_short = []
LIST_long = sorted(LIST_long, key=lambda x:(x[0], float(x[1]))) # <<-- here
for x, y in itertools.groupby(LIST_long, lambda x: x[0]):
LIST_short.append(list(y)[0])
print(LIST_short)
结果:
>>> LIST_short
[['1', '2.0'], ['2', '8.8']]
>>>
问题是,您将第二个元素作为字符串进行比较,而您应该将它们转换为 float
值进行比较。
【讨论】:
【参考方案3】:以下应该这样做:
LIST_long = [['1', '50.9'], ['1', '9.0'], ['1', '10.2'], ['1', '2.0'], ['2', '50.1'], ['2', '8.8']]
LIST_short = dict()
for id, value in LIST_long:
if id not in LIST_short or float(value) < float(LIST_short[id]):
LIST_short[id] = value
LIST_short = [[x, y] for x, y in LIST_short.items()]
【讨论】:
你的代码输出:LIST_short ->> [['1', '10.2'], ['2', '50.1']]
,这是错误的。以上是关于如何比较数字子列表中的第一项,如果重复,比较第二项并选择第二项最小的子列表?的主要内容,如果未能解决你的问题,请参考以下文章