【问题标题】:Indices of words that appear only once in a list列表中仅出现一次的单词索引
【发布时间】:2018-12-15 17:16:30
【问题描述】:

我有以下单词列表:

x = ['Gaga', 'Gaga', 'Lam', 'Reem', 'Pal', 'Gaga','Lam']

我需要删除只出现一次的单词,并返回索引或位置。

y = ['Gaga', 'Gaga', 'Lam', 'Gaga', 'Lam']

loc = [0, 0, 0, 1, 1, 0, 0]

有什么简单的功能可以做到这一点吗?

【问题讨论】:

  • 你有什么尝试吗?

标签: python string list indexing


【解决方案1】:

您可以使用collections.Counter 并隔离只出现一次的项目。然后使用列表推导来获得所需的结果。解决方案总体上是 O(n),尽管它涉及 3 次传递。

x = ['Gaga', 'Gaga', 'Lam', 'Reem', 'Pal', 'Gaga','Lam']

from collections import Counter

singles = {k for k, v in Counter(x).items() if v == 1}

y = [i for i in x if i not in singles]
loc = [int(i in singles) for i in x]

print(y, loc, sep='\n')

['Gaga', 'Gaga', 'Lam', 'Gaga', 'Lam']
[0, 0, 0, 1, 1, 0, 0]

【讨论】:

    【解决方案2】:

    您可以使用Counter 类来达到这个目的:

    from collections import Counter
    
    x = ['Gaga', 'Gaga', 'Lam', 'Reem', 'Pal', 'Gaga','Lam']
    
    c = Counter(x)
    
    new_values = [item for item in x if c[item] > 1]
    indexes = [1 if c[item] == 1 else 0 for item in x]
    
    print(new_values)
    print(indexes)
    

    输出是:

    ['Gaga', 'Gaga', 'Lam', 'Gaga', 'Lam']
    [0, 0, 0, 1, 1, 0, 0]
    

    【讨论】:

    • 请注意,O(n) 也是如此。但不是三元与int(c['item'] == 1) 的忠实粉丝。此外,由于您在两个列表推导中都测试了 c[item] == 1,因此效率比我的要低。
    【解决方案3】:

    带有 pandas 模块及其 pd.Series.duplicated() 函数的替代 one-liner

    In [80]: x = ['Gaga', 'Gaga', 'Lam', 'Reem', 'Pal', 'Gaga','Lam']
    
    In [81]: (~pd.Series(x).duplicated(keep=False)).astype(int).tolist()
    Out[81]: [0, 0, 0, 1, 1, 0, 0]
    

    要删除所有非重复项:

    In [85]: s = pd.Series(x)
    
    In [86]: s[s.duplicated(keep=False)].tolist()
    Out[86]: ['Gaga', 'Gaga', 'Lam', 'Gaga', 'Lam']
    

    【讨论】:

    • 次要点,更好的是计算s.duplicated(keep=False) 作为初始步骤并在您的计算中使用它。但是对于一个不错的 Panda 解决方案仍然 +1。
    • @jpp,当然,当将这两个组合到一个公共块中时,s = pd.Series(x)dups = s.duplicated(keep=False) 应该事先计算好。我将它们分开以进行演示pandas one-liners
    【解决方案4】:

    您能创建一个新列表并使用它吗?

    x = ['Gaga', 'Gaga', 'Lam', 'Reem', 'Pal', 'Gaga','Lam']
    loc = []
    new_x = []
    
    for name in x:
        if x.count(name) == 1:
            loc.append(1)
        else:
            loc.append(0)
            new_x.append(name)
    

    【讨论】:

      【解决方案5】:

      你也可以使用列表推导

      x = ['Gaga', 'Gaga', 'Lam', 'Reem', 'Pal', 'Gaga', 'Lam'] 
      y = [name for name in x if x.count(name) != 1]
      

      输出

      ['嘎嘎','嘎嘎','林','嘎嘎','林']

      【讨论】:

      • 这个方案在list的元素个数上有二次复杂度,不是最好的
      猜你喜欢
      • 1970-01-01
      • 2020-03-12
      • 2019-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-25
      • 1970-01-01
      相关资源
      最近更新 更多