2015-07-26 2 views
-1

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

Это проблема в книге «Think Python», которая просит написать функцию, чтобы вернуть True, содержит список любых дублирующих элементов или False в противном случае.

def has_duplicates(t): 
    for i in t: 
     if i in t.pop(t.index(i)): 
      return True 
    return False 
+1

возможно дубликат [поиск и список дубликатов в списке Python] (http://stackoverflow.com/questions/9835762/find-and-list-duplicates-in -python-list) –

+0

никогда не изменяйте список во время цикла! – Clodion

+0

Да, но ответы там используют набор. У меня есть задача не использовать set. – teamathematic

ответ

3

Что в этом плохого?

  • Вы удаляете элементы из t, итерации по нему. Это предотвращает работу итерации, как и следовало ожидать, в целом эффект заключается в пропуске элементов. Не делай это.

  • t.pop(t.index(i)) возвращает i (или значение, равное ей), так что все, что вы надеетесь достичь с помощью if i in, я не думаю, что вы добьетесь.

+0

Это не ответ, это комментарий. Plese удалите его и опубликуйте комментарий. – webzy

+0

@webzy «Привет, я просто хочу знать, что не так в моем коде». Я бы сказал, что это ответ. – juanchopanza

+0

ОК, нет проблем :-) – webzy

1

Вы можете протестировать его, сравнив длину списка с длиной набора, созданного из этого списка, потому что набор удаляет дубликаты.

def has_duplicates(t): 
    return len(t) > len(set(t)) 
+0

вы выиграли меня за 18 секунд ... –

+0

Поскольку вопросник ограничен, чтобы не использовать 'set' (который по какой-то причине остается до комментария), просто для удовольствия предположим, что элементы списка не хешируются. Например, возможно, они также перечислены :-) –

+0

@Amit Talmor Ha ha! Речь идет не о победе, а о помощи ;-) – webzy

0
def has_duplicates(t): 
    no_dup = list(set(t)) 
    if len(t) > len(no_dup): 
     return True 
    return False 
+0

Зачем делать список из набора? – juanchopanza

+0

Я думаю, что он пытался что-то выиграть, поэтому он набрал слишком быстро и имел опечатку ;-) – webzy

+0

@webzy Затем они должны были набрать меньше: 'return len (t)> len (set (t))'. – juanchopanza

-2

Ну, с список понимания (спасибо Steve Джессоп):

def has_duplicates(t): 
    return any(t.count(i)>1 for i in t) 

lst = [1, 2, 3, 4, 5, 6, 1, 5 ,6] 
print(has_duplicates(lst)) 

результат:

>>> 
True 
>>> 
+0

Это возвращает 'False' для ввода' [2,2] ', потому что' range (len (t)) 'должен быть просто' t' , 'Истина, если что-то еще False' может быть упрощено до' bool (something) ', хотя в этом случае' something' уже является логическим, поэтому просто 'something'. Кроме того, вы можете получить некоторую выгоду от короткого замыкания, выполнив 'any (t.count (i)> 1 для i в t)'. –

+0

Да, конечно! Я смотрю ваши комментарии! Благодаря! – Clodion

+0

@SteveJessop: Сценарий исправлен. – Clodion

-1

Прежде всего, никогда саботажа со списком в то время как итерация на нем. Во-вторых, ваш код проверяет, является ли i == элемент, re popping. Это всегда будет верно, поскольку, когда вы выходите на элемент python, вы возвращаете этот элемент. Поэтому бесполезно сравнивать его с i, потому что вы только что нажали. Это похоже на сравнение, если i == i .. Попробуйте использовать функцию t = ['1', '2', '3'] и используйте отладчик, чтобы проверить, что я говорю.

Вы можете сделать следующее, так как вы не можете использовать наборы:

def has_duplicates(t): 
    #first have a backup to keep the iteration clean 
    t_backup = t.copy() 
    for i in t_backup: 
     #first pop the item 
     t.pop(t.index(i)) 
     #then check if such item still exists 
     if i in t: 
      return True 
    return False 
Смежные вопросы