如何比较数字子列表中的第一项,如果重复,比较第二项并选择第二项最小的子列表?
How to compare first item in sublist of numbers, if repeated, compare the second item and pick the sublist with the smallest second item?
我有一个带数字的列表列表 (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'],...]
我在Python3.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 之前; 8 前 5 等等....
如果能帮助解决这个问题,我将不胜感激。
期待建议。
你可以使用字典来获取结果,将子列表的第一项存储为字典的键,并相应地添加第二项作为列表中的值,然后获取列表的最小值,你得到了要求的结果。
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']]
下面应该这样做:
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()]
您的代码完美运行,您只需将 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
值进行比较。
我有一个带数字的列表列表 (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'],...]
我在Python3.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 之前; 8 前 5 等等....
如果能帮助解决这个问题,我将不胜感激。 期待建议。
你可以使用字典来获取结果,将子列表的第一项存储为字典的键,并相应地添加第二项作为列表中的值,然后获取列表的最小值,你得到了要求的结果。
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']]
下面应该这样做:
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()]
您的代码完美运行,您只需将 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
值进行比较。