【问题标题】:Detect/remove duplicate values in a list检测/删除列表中的重复值
【发布时间】:2016-01-31 14:30:05
【问题描述】:

我想确定一个列表是否有重复值。我该怎么做?

我有 3 组列表:

Link_a =     ['a','b','c']    
Bookmark_a = ['1','2','3']    
Link_b =     ['b','c']    
Bookmark_b = ['4','5']    
Link_c =     ['a']    
Bookmark_c = ['6']

我想将其简化为一组链接和一组书签,如下所示:

Answer_link_all =     ['a','b','c']    
Answer_bookmark_all = ['7', '6', '8']

我第一次尝试link_a + link_b,但发现值会重复:

link_a + link_b   # result: ['a', 'b', 'c', 'b', 'c']

我想我想做的就是这样的伪代码:

if name is repeat pass    
   or add tag name

但还有书签要计算,我不知道如何进行。

【问题讨论】:

  • 为什么 Answer_bookmark_all = ['7', '6', '8']?
  • 什么鬼,伙计?也许谷歌翻译能帮上忙?
  • 我有点明白这一点。因此,只有当变量不存在于上一个列表中并且如果它已经存在时,您才想将其添加到列表中,然后将值添加到书签中?
  • @BAE:看起来 OP 正在计算每个 'a''b''c' 的总数。例如,Link_a / Bookmark_a 对将“a”映射到 1,Link_c / Bookmark_c 对将“a”映射到 6;因此,“a”的总数为 7。“b”和“c”也是如此。
  • @BhargavRao 是的! ,对不起我的英语不好

标签: python python-2.7


【解决方案1】:

您最好使用字典,而不是为标签及其值使用不连贯的列表。此外,请考虑使用实际整数作为值,而不是字符串。

这里有一个建议:

>>> from collections import Counter
>>> c = Counter()
>>> c.update(dict((x,int(y)) for x,y in zip(Link_a, Bookmark_a)))
>>> c.update(dict((x,int(y)) for x,y in zip(Link_b, Bookmark_b)))
>>> c.update(dict((x,int(y)) for x,y in zip(Link_c, Bookmark_c)))
>>> c
Counter({'c': 8, 'a': 7, 'b': 6})

每当您获得新数据时,相应地更新您的计数器。像这样访问计数器:

>>> c['a']
7
>>> c['b']
6
>>> c['c']
8

【讨论】:

  • @busystudent 没问题,下次请尝试问一个更准确的问题,你让我有一段时间很困惑。
【解决方案2】:

您可以zip 不同的列表对,

Link_a =     ['a','b','c']    
Bookmark_a = ['1','2','3']    
Link_b =       ['b','c']    
Bookmark_b =  ['4','5']    
Link_c =     ['a']    
Bookmark_c = ['6']

zps = [
    zip(Link_a, Bookmark_a),
    zip(Link_b, Bookmark_b),
    zip(Link_c, Bookmark_c),
]

d = dict()
for z in zps:
    for k,v in z:
        v = int(v) # Converting v to a number 
        if k not in d: d[k] = v; continue
        d[k] += v

Answer_link_all = list(d.keys())
Bookmark_link_all = list(d.values())

【讨论】:

  • 哇我不知道python有zip,我想我应该学习一下,谢谢你的回答!!
【解决方案3】:

我会选择这样的:

Link_a =     ['a','b','c']    
Bookmark_a = ['1','2','3']    
Link_b =       ['b','c']    
Bookmark_b =  ['4','5']    
Link_c =     ['a']    
Bookmark_c = ['6']


def to_dict(a,b):
    return {k: int(v) for k, v in zip(a,b)}


def merge_dicts(x,y):
    return { k:x.get(k, 0) + y.get(k, 0) for k in set(x) | set(y) }


res = merge_dicts(to_dict(Link_a, Bookmark_a), to_dict(Link_b, Bookmark_b))
res = merge_dicts(res, to_dict(Link_c, Bookmark_c))

print res

结果:{'a': 7, 'c': 8, 'b': 6}

【讨论】:

  • 谢谢你的回答!!真不知道def能不能写出这段代码。
  • 我的荣幸。如果它有帮助,您可以投票(左上箭头)。你看懂代码还是需要解释一下?
【解决方案4】:

这是sets 的完美用例,它是在 Python 3.x 中引入的,但已向后移植到 Python 2.7。

您当前使用的列表是有序的、连续的一系列值。如您所见,这些值可以重复,您必须做额外的工作才能将列表汇总为唯一的值。

与列表一样,集合是值的集合。但是,它们不是有序的,也不是顺序的。此外,在一个集合中,一个值不能重复。如果向集合添加值,并且它已经是集合的成员,则不会得到重复值;它仍然只在集合中出现一次。

集合是根据数学中的集合建模的。

(以下示例假设 Python 2.7 - Python 3 中的语法略有不同。)

您可以使用文字符号创建一个集合:

Link_a = set(['a','b','c'])

一个警告 - 如果您传递一个字符串,它会将字符串拆分为其组成字母。那是因为在 Python 中,字符串也是可迭代的。

Link_a = set('abc')     # now: set(['a', 'c', 'b'])

你可以通过传递一个单元素元组或列表来解决这个问题。

Link_a = set(('abc',))  # now: set(['abc'])
Link_a = set(['abc'])   # now: set(['abc'])

您也可以创建一个空集,然后添加到它。

Link_a = set()                    # now: set([])
Link_a.update(['a', 'b', 'c'])    # now: set(['a', 'c', 'b'])
Link_a.update('d')                # now: set(['a', 'c', 'b', 'd'])
Link_a.update('a')                # now: set(['a', 'c', 'b', 'd'])

如您所见,我们所做的最后一个update (a) 并没有更改设置。 a 已经是一个集合成员,所以当我们再次尝试添加它时没有任何反应。

注意:从示例中可以看出,集合是无序的。如果您依赖于按特定顺序排列的值,则集合可能不适合您(或者,您可能需要在使用它们时以某种方式对它们进行排序)。

与列表一样,您可以使用推导式,您可以使用in 测试成员资格...

'd' in Link_a    # True
'z' in Link_a    # False

您还可以对集合使用数学运算。

a & b       # Intersection: members which appear in both sets
a | b       # Union: all members from both sets
a - b       # Difference: members which are in a, but not in b
a ^ b       # Exclusive or (XOR): members in either a or b, but not in both

要将您的列表组合成一个最终集合,您可以使用联合:

Link_a =     set(['a','b','c'])
Bookmark_a = set(['1','2','3'])
Link_b =     set(['b','c'])
Bookmark_b = set(['4','5'])
Link_c =     set(['a'])
Bookmark_c = set(['6'])

Answer_link_all = set(Link_a | Link_b | Link_c)
Answer_bookmark_all = set(Bookmark_a | Bookmark_b | Bookmark_c)

如果您使用的是 Python 3,情况会有些不同。大部分情况是相同的,只是您也可以使用这种文字表示法声明集合。

setName = {1, 2, 3, 2, 3, 1}      # result: class 'set': {1, 2, 3}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 1970-01-01
    • 2020-08-04
    • 2019-06-12
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多