Как устранить дубликаты записей в Python, сохраняя при этом чувствительность к регистру?

Я ищу способ удалить повторяющиеся записи из списка Python, но с твистом; Окончательный список должен быть чувствительным к регистру с предпочтением слов верхнего регистра.

Например, между cup и Cup мне нужно только держать Cup а не cup . В отличие от других распространенных решений, которые предлагают сначала использовать метод lower() , я бы предпочел сохранить здесь строку, и, в частности, я предпочел бы сохранить ее с прописной буквой над строкой в ​​нижнем регистре.

Опять же, я пытаюсь включить этот список: [Hello, hello, world, world, poland, Poland]

в это:

[Hello, world, Poland]

Как мне это сделать?

Заранее спасибо.

    4 Solutions collect form web for “Как устранить дубликаты записей в Python, сохраняя при этом чувствительность к регистру?”

    Это не сохраняет порядок words , но он создает список «уникальных» слов с предпочтением капитализированных.

     In [34]: words = ['Hello', 'hello', 'world', 'world', 'poland', 'Poland', ] In [35]: wordset = set(words) In [36]: [item for item in wordset if item.istitle() or item.title() not in wordset] Out[36]: ['world', 'Poland', 'Hello'] 

    Если вы хотите сохранить заказ так, как они появляются в words , то вы можете использовать коллекции.OrderedDict :

     In [43]: wordset = collections.OrderedDict() In [44]: wordset = collections.OrderedDict.fromkeys(words) In [46]: [item for item in wordset if item.istitle() or item.title() not in wordset] Out[46]: ['Hello', 'world', 'Poland'] 

    Использование set для отслеживания замеченных слов:

     def uniq(words): seen = set() for word in words: l = word.lower() # Use `word.casefold()` if possible. (3.3+) if l in seen: continue seen.add(l) yield word 

    Применение:

     >>> list(uniq(['Hello', 'hello', 'world', 'world', 'Poland', 'poland'])) ['Hello', 'world', 'Poland'] 

    ОБНОВИТЬ

    Предыдущая версия не заботится о предпочтении прописных букв в нижнем регистре. В обновленной версии я использовал min как @TheSoundDefense.

     import collections def uniq(words): seen = collections.OrderedDict() # Use {} if the order is not important. for word in words: l = word.lower() # Use `word.casefold()` if possible (3.3+) seen[l] = min(word, seen.get(l, word)) return seen.values() 

    Поскольку прописная буква «меньше», чем строчная буква в сравнении, я думаю, вы можете это сделать:

     orig_list = ["Hello", "hello", "world", "world", "Poland", "poland"] unique_list = [] for word in orig_list: for i in range(len(unique_list)): if unique_list[i].lower() == word.lower(): unique_list[i] = min(word, unique_list[i]) break else: unique_list.append(word) 

    В min будет предпочтительнее использовать слова с заглавными буквами ранее.

    Некоторые лучшие ответы здесь, но, надеюсь, что-то простое, разные и полезные. Этот код удовлетворяет условиям вашего теста, последовательным парам совпадающих слов, но не справится с чем-либо более сложным; таких как непоследовательные пары, не-пары или нестрочные. Все сложнее, и я бы принял другой подход.

     p1 = ['Hello', 'hello', 'world', 'world', 'Poland', 'poland'] p2 = ['hello', 'Hello', 'world', 'world', 'Poland', 'Poland'] def pref_upper(p): q = [] a = 0 b = 1 for x in range(len(p) /2): if p[a][0].isupper() and p[b][0].isupper(): q.append(p[a]) if p[a][0].isupper() and p[b][0].islower(): q.append(p[a]) if p[a][0].islower() and p[b][0].isupper(): q.append(p[b]) if p[a][0].islower() and p[b][0].islower(): q.append(p[b]) a +=2 b +=2 return q print pref_upper(p1) print pref_upper(p2) 
    Python - лучший язык программирования в мире.