Добавить только уникальные значения в список в python
Я пытаюсь изучить python. Вот соответствующая часть упражнения:
Для каждого слова, проверьте, нет ли слова в списке. Если слова нет в списке, добавьте его в список.
Вот что у меня есть.
fhand = open('romeo.txt')
output = []
for line in fhand:
words = line.split()
for word in words:
if word is not output:
output.append(word)
print sorted(output)
Вот что я получаю.
['Arise', 'But', 'It', 'Juliet', 'Who', 'already', 'and', 'and', 'and', 'breaks', 'east', 'envious', 'fair', 'grief', 'is', 'is', 'is', 'kill', 'light', 'moon', 'pale', 'sick', 'soft', 'sun', 'sun', 'the', 'the', 'the', 'through', 'what', 'window', 'with', 'yonder']
Примечание: дублирование (и, есть, солнце и т.д.).
Как получить только уникальные значения?
Ответы
Ответ 1
Чтобы исключить дубликаты из списка, вы можете сохранить вспомогательный список и проверить.
myList = ['Arise', 'But', 'It', 'Juliet', 'Who', 'already', 'and', 'and', 'and',
'breaks', 'east', 'envious', 'fair', 'grief', 'is', 'is', 'is', 'kill', 'light',
'moon', 'pale', 'sick', 'soft', 'sun', 'sun', 'the', 'the', 'the',
'through', 'what', 'window', 'with', 'yonder']
auxiliaryList = []
for word in myList:
if word not in auxiliaryList:
auxiliaryList.append(word)
выход:
['Arise', 'But', 'It', 'Juliet', 'Who', 'already', 'and', 'breaks', 'east',
'envious', 'fair', 'grief', 'is', 'kill', 'light', 'moon', 'pale', 'sick',
'soft', 'sun', 'the', 'through', 'what', 'window', 'with', 'yonder']
Это очень просто понять, а код говорит сам за себя. Однако простота кода достигается за счет эффективности кода, поскольку линейное сканирование растущего списка приводит к ухудшению линейного алгоритма до квадратичного.
Используйте set() !, Набор представляет собой неупорядоченную коллекцию без повторяющихся элементов.
Основное использование включает тестирование членства и устранение дублирующих записей.
auxiliaryList = list(set(myList))
выход:
['and', 'envious', 'already', 'fair', 'is', 'through', 'pale', 'yonder',
'what', 'sun', 'Who', 'But', 'moon', 'window', 'sick', 'east', 'breaks',
'grief', 'with', 'light', 'It', 'Arise', 'kill', 'the', 'soft', 'Juliet']
Ответ 2
Вместо is not
operator, вы должны использовать not in
operator, чтобы проверить, есть ли элемент в списке:
if word not in output:
Кстати, использование set
намного эффективнее (см. "Сложность времени"):
with open('romeo.txt') as fhand:
output = set()
for line in fhand:
words = line.split()
output.update(words)
ОБНОВЛЕНИЕ set
не сохраняет первоначальный порядок. Чтобы сохранить порядок, используйте набор в качестве вспомогательной структуры данных:
output = []
seen = set()
with open('romeo.txt') as fhand:
for line in fhand:
words = line.split()
for word in words:
if word not in seen: # faster than 'word not in output'
seen.add(word)
output.append(word)
Ответ 3
Здесь "однострочный", который использует эту реализацию для удаления дубликатов при сохранении порядка:
def unique(seq):
seen = set()
seen_add = seen.add
return [x for x in seq if not (x in seen or seen_add(x))]
output = unique([word for line in fhand for word in line.split()])
Последняя строка выравнивает fhand
в список слов, а затем вызывает unique()
в результирующем списке.
Ответ 4
Один из способов - увидеть, есть ли он в списке до добавления, что и делает ответ Тони. Если вы хотите удалить повторяющиеся значения после создания списка, вы можете использовать set()
чтобы преобразовать существующий список в набор уникальных значений, а затем использовать list()
чтобы снова преобразовать его в список. Все в одной строке:
list(set(output))
Если вы хотите отсортировать по алфавиту, просто добавьте sorted()
к приведенному выше. Вот результат:
['Arise', 'But', 'It', 'Juliet', 'Who', 'already', 'and', 'breaks', 'east', 'envious', 'fair', 'grief', 'is', 'kill', 'light', 'moon', 'pale', 'sick', 'soft', 'sun', 'the', 'through', 'what', 'window', 'with', 'yonder']