【问题标题】:Find duplicates in a list of strings differing only in upper and lower case writing在仅大小写不同的字符串列表中查找重复项
【发布时间】:2021-01-02 23:09:24
【问题描述】:

我有一个字符串列表,其中包含 'literal duplicates''pseudo-duplicates',它们仅在小写和大写方面有所不同。我正在寻找一个函数,它将所有文字重复项视为一组,返回它们的索引,并找到这些元素的所有伪重复项,再次返回它们的索引。

这是一个示例列表:

a = ['bar','bar','foo','Bar','Foo','Foo']

这是我正在寻找的输出(列表列表的列表):

dupe_list = [[[0,1],[3]],[[2],[4,5]]]

解释:'bar' 在索引 0 和 1 处出现两次,在索引 3 处有一个伪重复 'Bar''foo' 在索引 2 处出现一次,在索引处有两个伪重复 'Foo' 4 和 5。

【问题讨论】:

  • bArbARfOo 的可能性吗?
  • 是的,唯一重要的是字符本身相等,但仅在一个或多个位置的小写或大写方面有所不同。它不一定是字符串的开头。

标签: python list duplicates


【解决方案1】:

这是一种解决方案(您没有阐明列表项的逻辑是什么,我认为您希望项目采用较低格式,因为它们在列表中从左到右满足,请告诉我是否必须不同):

d={i:[[], []] for i in set(k.lower() for k in a)}

for i in range(len(a)):
    if a[i] in d.keys():
        d[a[i]][0].append(i)
    else:
        d[a[i].lower()][1].append(i)

result=list(d.values())

输出:

>>> print(result)

[[[0, 1], [3]], [[2], [4, 5]]]

【讨论】:

  • 你不必为那个genex做一个set,你可以直接迭代
  • 我觉得不错!您的解决方案还考虑了 cmets 中提到的 @python_user ('FoO' 是 'foo' 的伪副本)。我不太明白您的问题,您所说的列表项逻辑是什么意思?你的意思是说列表中有某种顺序吗?如果你的意思是,不,如果我的问题中的字符串会随机打乱,该函数也应该起作用。如果这是您的问题,请告诉我。
  • 我的意思是什么将代表结果列表的项目?当它们在原始列表中从左到右遇到时,它们是否会以小写字母('bar'、'foo')表示唯一的单词?如果是,那么我的解决方案可以正常工作。但是逻辑可能不同,例如,您可能希望表示列表中单词的第一个变体(例如,它可能是“Bar”、“foO”)。例如 ['Bar', 'bar', 'bar'] 在第一种情况下会产生 [[2,3], [1]] 而在第二种情况下会产生 [[1], [2,3]]跨度>
  • 更简单地说,核心词是什么(将在结果列表的左侧项目中表示)?是小写的单词,还是列表中遇到的单词的第一个变体?
  • 嗯,好的,现在我明白了。不,结果列表中有某种顺序并不重要,因此您当前的解决方案有效(至少对我而言!)。但是,将其作为附加组件肯定会很好。随意将此功能添加到您的解决方案中,我认为它可能对其他人有所帮助。
【解决方案2】:

这就是我将如何实现它。但是您应该考虑使用字典而不是列表列表。字典是解决此类问题的优秀数据结构。

#default argument vars
a = ['bar','bar','foo','Bar','Foo','Foo']

#initalize a dictionary to count occurances
a_dict = {}
for i in a:
    a_dict[i] = None

#loop through keys in dictionary, which is values from a_list
    #loop through the items from list a
    #if the item is exact match to key, add index to list of exacts
    #if the item is similar match to key, add index to list of similars
#update the dictionary key's value 
for k, v in a_dict.items():
    index_exact = []
    index_similar = []
    for i in range(len(a)):
        print(a[i])
        print(a[i] == k)
        if a[i] == str(k):
            index_exact.append(i)
        elif a[i].lower() == str(k):
            index_similar.append(i) 
    a_dict[k] = [index_exact, index_similar]

#print out dictionary values to assure answer
print(a_dict.items())

#segregate values from dictionary to its own list.
dup_list = []
for v in a_dict.values():
    dup_list.append(v)
print(dup_list)

【讨论】:

    【解决方案3】:

    这里是解决方案。我已经处理了仅存在伪重复项或仅存在字面重复项的情况

    a = ['bar', 'bar', 'foo', 'Bar', 'Foo', 'Foo', 'ka']
    # Dictionaries to store the positions of words 
    literal_duplicates = dict()
    pseudo_duplicates = dict()
    
    for index, item in enumerate(a):
        # Treates words as literal duplicates if word is in smaller case
        if item.islower():
            if item in literal_duplicates:
                literal_duplicates[item].append(index)
            else:
                literal_duplicates[item] = [index]
                # Handle if only literal_duplicates present             
                if item not in pseudo_duplicates:
                    pseudo_duplicates[item] = []
    
        # Treates words as pseudo duplicates if word is in not in smaller case
        else:
            item_lower = item.lower()
            if item_lower in pseudo_duplicates:
                pseudo_duplicates[item_lower].append(index)
            else:
                pseudo_duplicates[item_lower] = [index]
                # Handle if only pseudo_duplicates present
                if item not in literal_duplicates:
                    literal_duplicates[item_lower] = []
    
    # Form final list from the dictionaries
    dupe_list = [[v, pseudo_duplicates[k]] for k, v in literal_duplicates.items()]
    

    【讨论】:

    • 示例a = ['bar','bar','foo','Bar','Foo','Foo', 'bAr', 'baR', 'FOo', 'Caa', 'ddd'] 的可能输出为[[[0, 1], [3, 6, 7]], [[2], [4, 5, 8]], [[], [9]], [[10], []]]
    【解决方案4】:

    这里给你一个简单易懂的答案

    a = ['bar','bar','foo','Bar','Foo','Foo']
    dupe_list = []
    ilist = []
    ilist2 =[]
    samecase = -1
    dupecase = -1
    for i in range(len(a)):
        if a[i] != 'Null':
            ilist = []
            ilist2 = []
            for j in range(i+1,len(a)):
                samecase = -1
                dupecase = -1
                # print(a)
                if i not in ilist:
                    ilist.append(i)
                if a[i] == a[j]:
                    # print(a[i],a[j])
                    samecase = j
                    a[j] = 'Null'
                elif a[i] == a[j].casefold():
                    # print(a[i],a[j])
                    dupecase = j
                    a[j] = 'Null'
                # print(samecase)
                # print(ilist,ilist2)
                if samecase != -1:
                    ilist.append(samecase)
                if dupecase != -1:
                    ilist2.append(dupecase)
            dupe_list.append([ilist,ilist2])
            a[i]='Null'
    print(dupe_list)
    

    【讨论】:

      猜你喜欢
      • 2021-12-16
      • 2015-04-22
      • 1970-01-01
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      • 2019-11-17
      • 2015-07-15
      • 1970-01-01
      相关资源
      最近更新 更多