繁体   English   中英

列表保持此值在 2 中最高

[英]list keep this value the highest among 2

您好,我有一个包含姓名、名字和结果的列表。 我想创建一个没有重复的新列表。在这种情况下,“M”存在两次,所以我只想保留他的最好成绩。

我写了这段代码,但它让我重复。

我希望在 output 中:

[['L', 'l', '7.69'], ['M', 'm', '9.10'], ['N', 'n', '7.69'], ['O', 'o', '5.90']]

你能帮助我吗? 谢谢你。

list_no_ok = [['L', 'l', '7.69'], ['M', 'm', '4.10'], ['M', 'm', '9.10'], ['N', 'n', '7.69'], ['O', 'o', '5.90']]
list_ok = []

for i, next_i in zip(list_no_ok, list_no_ok[1::]):

    if i[0] == next_i[0] and i[1] == next_i[1]:
        if i[6] > next_i[6]:
            lala = [i[0], i[1], i[2], i[6]]
        else:
            lala = [next_i[0], next_i[1], next_i[2], next_i[6]]
    else:
        lala = [i[0], i[1], i[2], i[6]]

    list_ok.append(lala)

print(list_ok)

使用 hash 的方法非常天真,一点也不聪明。 遍历列表。 对于列表中的每个列表,第一个元素是键。 与列表中已与该键关联的第三个值进行比较。 当然,如果我们还没有查看那个键,就会抛出异常。 我们可以通过使用当前密钥将当前列表添加到 hash 来处理这个问题。

我们可以通过使用values并将其转换为 list 来获得我们想要的list

>>> a = [['L', 'l', '7.69'], ['M', 'm', '4.10'], ['M', 'm', '9.10'], ['N', 'n', '7.69'], ['O', 'o', '5.90']]
>>> h = {}
>>> for x in a:
...     key = x[0]
...     try:
...          if h[key][2] < x[2]:
...              h[key] = x
...     except KeyError:
...          h[key] = x
...
>>> h
{'L': ['L', 'l', '7.69'], 'M': ['M', 'm', '9.10'], 'N': ['N', 'n', '7.69'], 'O': ['O', 'o', '5.90']}
>>> list(h.values())
[['L', 'l', '7.69'], ['M', 'm', '9.10'], ['N', 'n', '7.69'], ['O', 'o', '5.90']]

我建议您使用字典来跟踪每个人的哪一行得分最高,然后遍历行,更新字典,除非该人已经看到了更好的分数。

字典的键是名称和名字的二元元组。

最后,output 包含在字典中的值。

list_ok = [['L', 'l', '7.69'],
           ['M', 'm', '9.10'],
           ['M', 'm', '9.10'],
           ['N', 'n', '7.69'],
           ['O', 'o', '5.90']]

bests = {}

def score_from_row(row):
    return float(row[2])

for row in list_ok:

    key = (row[0], row[1])
    score = score_from_row(row)

    if key in bests:
        previous_best = bests[key]
        if score_from_row(previous_best) > score:
            continue

    bests[key] = row

print(list(bests.values()))

这给出了:

[['L', 'l', '7.69'], ['M', 'm', '9.10'], ['N', 'n', '7.69'], ['O', 'o', '5.90']]

假设所有元素都“完成”,这里是代码

def deDupe():
    list_ok = [['L', 'l', 'Finished', '7.69'], ['M', 'm', 'Finished', '9.10'], ['M', 'm', 'Finished', '9.10'],
               ['N', 'n', 'Finished', '7.69'], ['O', 'o', 'Finished', '5.90']]
    capture_dict = {}
    for element in list_ok:
        keyValue = '{0}{1}'.format(element[0], element[1])
        if keyValue in list(capture_dict.keys()):
            compare_value = capture_dict[keyValue]
            if float(element[3]) > float(compare_value[3]):
                capture_dict.pop(keyValue)
                capture_dict[keyValue] = element
        else:
            capture_dict[keyValue] = element
    list_2 = list(capture_dict.values())
    print(list_2)

Output:

>>> deDupe()
[['L', 'l', 'Finished', '7.69'], ['M', 'm', 'Finished', '9.10'], ['N', 'n', 'Finished', '7.69'], ['O', 'o', 'Finished', '5.90']]

对于短代码,您可以使用itertools.groupby

from itertools import groupby

list_no_ok = [['L', 'l', '7.69'], ['M', 'm', '4.10'], ['M', 'm', '9.10'], ['N', 'n', '7.69'], ['O', 'o', '5.90']]

output = [next(g) for _, g in groupby(sorted(list_no_ok, key=lambda x: (x[0], x[1], -float(x[2]))), lambda x: (x[0], x[1]))]
print(output) # [['L', 'l', '7.69'], ['M', 'm', '9.10'], ['N', 'n', '7.69'], ['O', 'o', '5.90']]

如果您不想导入模块,则可以使用字典:

list_no_ok = [['L', 'l', '7.69'], ['M', 'm', '4.10'], ['M', 'm', '9.10'], ['N', 'n', '7.69'], ['O', 'o', '5.90']]
output = {}
for name, first, result in list_no_ok:
    output[(name, first)] = max(output.get((name, first), 0), float(result)) # sequentially update
output = [[name, first, f"{result:.2f}"] for (name, first), result in output.items()] # convert back to list
print(output) # [['L', 'l', '7.69'], ['M', 'm', '9.10'], ['N', 'n', '7.69'], ['O', 'o', '5.90']]

这是一种解析列表并在dictionary中存储值并检查当前结果与迄今为止看到的最高结果的方法。

为什么是字典? 字典只能存储唯一的键,所以每次我们遇到一个名字时,比如'M','m',我们可以确保我们只存储那个名字对的一个结果。

high_values = {} for name, first_name, 结果为 list_no_ok:

# To properly check the result values, convert to a float.
result = float(result)

# This step looks in the dictionary to see if a key that matches
#     the name, first_name tuple exists and if yes, will get the 
#     stored result so we can check to see if the next result is 
#     higher.
current_value = highest_values.get((name, first_name), 0)

# Here we check for the highest value and if the current result
#     is higher than the stored value, then we replace it with the
#     new higher value
if result > current_value:
    highest_values[(name, first_name)] = result

在这里,我们生成最终列表

list_ok = []
for names, result in highest_values.items():
    name, first_name = names
    list_ok.append([name, first_name, result])

print(list_ok)

[['L', 'l', 7.69], ['M', 'm', 9.1], ['N', 'n', 7.69], ['O', 'o', 5.9]]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM