如何按特定索引检查,删除列表中的重复列表?

huangapple go评论79阅读模式
英文:

How to delete the dulplicate list in list of list if I want to check by spetific index?

问题

I can help you translate the code-related part of your text. Here's the translation:

所以我尝试通过仅检查列表中的一个元素来删除列表中的重复列表我只知道如何从普通列表中删除重复项你们可以帮助我吗谢谢

所以我想要做的是仅附加每个名称的一个列表我已经对其进行了排序并且每个人的最大值将是相同名称中另一个值的第一个值

输入liz = [['Lina', 60], ['Gaga', 0], ['Dene', 100], ['Dene', 80], ['Dene', 0], ['Helen', 0], ['Will', 100]]
预期输出lix = [['Lina', 60], ['Gaga', 0], ['Dene', 100], ['Helen', 0], ['Will', 100]]

我已经尝试过但它只是将所有列表附加到列表中因为它与所有最近的不相等因为它的索引[1]的值

lix = []
for ele in liz:
        if ele not in lix:
            lix.append(ele)

Please note that the translation is for the code-related part of your text, as requested.

英文:

So I try to delete the duplicate list in list of list by checking just from only one element in that list. I only know to delete the duplicate from normal list, can you guys help me? Thanks!

So what I want to do is append just ONLY one list per name which I have sort it and the most value of each person will be the first one of another value in the same name.

input : liz = [['Lina', 60], ['Gaga', 0], ['Dene', 100], ['Dene', 80], ['Dene', 0], ['Helen', 0], ['Will', 100]]
expected output : lix = [['Lina', 60], ['Gaga', 0], ['Dene', 100], ['Helen', 0], ['Will', 100]]

What I have try to reach it and it just append all of list into list because it isn't equal to recent of all because its value of index[1]:

lix = []
for ele in liz:
        if ele not in lix:
            lix.append(ele)

答案1

得分: 1

为此,您可以简单地记录已经在列表中的所有名称并进行比较。

lix = {}  # 使用字典而不是列表
for pair in liz:
    if pair[0] in lix:
        if lix[pair[0]] < pair[1]:  # 如果不是最大值,添加最大值
            lix[pair[0]] = pair[1]
    else:
        lix[pair[0]] = pair[1]
英文:

To do so, you can simply have a record of all the names that are already in the list and compare them.

lix = {} # use dict instead of list
for pair in liz:
    if pair[0] in lix:
        if lix[pair[0]] &lt; pair[1]: # if it is not the largest, add the largest
            lix[pair[0]] = pair[1]
    else:
        lix[pair[0]] = pair[1]

答案2

得分: 1

为了保留每个不同字符串遇到的第一个数字,你可以将列表反向输入到字典构造器中,然后将项转换回列表的列表。因为字典构造器每个键只保留一个项,当提供重复项时,它会更新现有项。因此,反向顺序确保第一次出现的项最后加载到字典中,并成为最终的值。

liz = [['Lina', 60], ['Gaga', 0], ['Dene', 100], ['Dene', 80], 
       ['Dene', 0], ['Helen', 0], ['Will', 100]]

lix = [*{L[0]:L for L in liz[::-1]}.values()][::-1]

print(lix)

[['Lina', 60], ['Gaga', 0], ['Dene', 100], ['Helen', 0], ['Will', 100]]

另一种方法是使用一个存储已见字符串的集合,你在遍历项时检查并筛选或增补这个集合:

seen = set()
lix = [L for L in liz if not (L[0] in seen or seen.add(L[0])]

同样,可以在没有集合的情况下完成,但由于需要进行顺序搜索来检查每个项,所以运行速度会慢得多:

lix = list()
lix.extend(L for L in liz if all(L[0] != used for used,*_ in lix))

如果你的列表的排序顺序已经将重复的名称分组在一起(并且对于重复的名称,数字是按降序排列的),你可以直接使用itertools中的groupby函数:

from itertools import groupby
lix = [L for _, (L, *_) in groupby(liz, lambda i: i[0])]

如果没有排序,你可以使用一个复合键来对其进行排序:

liz.sort(key=lambda x: (x[0], -x[1]))

# 对相同名称的数字采用降序排列

请注意,liz.sort(reverse=True)也可以工作,但会以字母顺序相反的方式给出名称。

如果你不想对列表进行排序,但希望每个名称的数字最大,你可以使用一个简单的for循环构建所选子列表的字典,并将其值用作最终输出:

selected = dict()
for L in liz:
    if L[0] not in selected or L[1] > selected[L[0]][1]:
        selected[L[0]] = L
lix = list(selected.values())
英文:

To keep the first number encountered for each distinct string, you can feed your list in reverse to a dictionary constructors. Then convert the items back into a list of lists. Because the dictionary constructor will only hold one item per key it updates the existing item when duplicates are supplied. So, the reversed order ensures that the first occurrences are loaded last in the dictionary and end up being the value at the end.

liz = [[&#39;Lina&#39;, 60], [&#39;Gaga&#39;, 0], [&#39;Dene&#39;, 100], [&#39;Dene&#39;, 80], 
       [&#39;Dene&#39;, 0], [&#39;Helen&#39;, 0], [&#39;Will&#39;, 100]]

lix = [*{L[0]:L for L in liz[::-1]}.values()][::-1]

print(lix)

[[&#39;Lina&#39;, 60], [&#39;Gaga&#39;, 0], [&#39;Dene&#39;, 100], [&#39;Helen&#39;, 0], [&#39;Will&#39;, 100]]

Another way to do this is to use a set of seen values that you check to filter and augment as you go through the items:

seen = set()
lix = [L for L in liz if not (L[0] in seen or seen.add(L[0]))]

the same can be done without a set but would run much slower because of the sequential search process used to check every item:

lix = list()
lix.extend(L for L in liz if all(L[0] != used for used,*_ in lix) )

If the sort order of your list already has the duplicate names in consecutive groups (and numbers in decreasing order for duplicate names), you can use the groupby function from itertools directly:

from itertools import groupby
lix = [L for _,(L,*_) in groupby(liz,lambda i:i[0])]

If it is not sorted, you can use a composite key to sort it:

liz.sort(key=lambda x:(x[0],-x[1]))  

# negating x[1] produces a decreasing order of numbers for identical names

Note that liz.sort(reverse=True) would also work but would give you the names in reversed alphabetical order

If you don't want to sort your list at all but want the largest numbers for each name, you can build a dictionary of selected sub-lists with a simple for-loop and use its values as the final output:

selected = dict()
for L in liz:
    if L[0] not in selected or L[1] &gt; selected[L[0]][1]:
        selected[L[0]] = L
lix = list(selected.values())

huangapple
  • 本文由 发表于 2023年3月1日 12:20:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75599543.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定