2015-02-21 3 views
3

У меня есть небольшая проблема с некоторым кодированием. Это мой код:Как проверить, совпадают ли два числа в списке в Python

def sites(x): 
    r = [] 
    sum = 0 
    i = 0 
    modulo = [] 
    som = 0 
    j = 0 
    while i < len(x): 
     sum = int(float(x[i])) + (i + 1) 
     r.append(sum) 
     i = i + 1 
    while j < len(x): 
     som = r[j] % len(x) 
     modulo.append(som) 
     j = j + 1 
    return modulo 

Если я, например, заполнить сайтов («321») этот код даст мне список [1, 1, 1]. Я хочу проверить, есть ли в этом списке номера одинаковые. Я думал о чем-то вроде:

if modulo[0] != modulo[1] != modulo[2]: 
    print "valid" 
else: 
    print "invalid" 

Это работает, только если вход на сайтах имеет три цифры. Я занимался мозговым штурмом о том, как использовать цикл while, который проверяет каждую цифру.

Вся помощь очень приветствуется.

ответ

3

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

if len(set(modulo)) == len(modulo): # if lengths are equal we have no duplicate nums 
    print "valid" 
else: 
     print "Invalid" 

Если вы просто хотите, чтобы избежать добавления Dups сохранить набор всех Nums видел и проверить, прежде чем добавить:

seen = set() 
if num not in seen: add it 

Я хотел бы также избежать использования суммы в качестве имени переменной, как это тени встроенного Python sum функцию.

Вы также можете использовать enumerate, range и вам не нужно объявлять переменные в Python:

def sites(x): 
    r = [] 
    modulo = [] 
    ln = len(x) 
    for i,ele in enumerate(x): 
     sm = int(float(ele)) + (i + 1) 
     r.append(sm) 
    for j in range(ln): 
     som = r[j] % ln 
     modulo.append(som) 
    return modulo 

Или лучше снова использовать list comprehensions:

def sites(x): 
    ln = len(x) 
    r = [int(float(ele)) + (i + 1) for i,ele in enumerate(x)] 
    modulo = [r[j] % ln for j in range(ln)] 
    return modulo 
+0

спасибо! Я думал о том, как решить его более двух часов, и вы заходите с умным решением в течение первых двух минут запроса. Я не могу выразить, насколько я благодарен. Хороший день :) – Robbebeest

2

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

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

gen = ((int(float(ele)) + (i + 1)) % len(x) for i,ele in enumerate(x)) 
seen = set() 
for i in gen: 
    if i in seen: 
     print 'invalid' 
     break 
    seen.add(i) 
else: 
    print 'valid' 

Это имеет дополнительное преимущество, не создавая дополнительные 1-2 списков памяти, которая может быть проблемой, если ваша начальная строка/список очень велика.

+0

Это не очень эффективное решение, так как вы используете список, поэтому lookups являются '0 (n)' в отличие от 'set', который я предложил, который является' 0 (1) ', и в худшем случае вы все еще создайте второй список 'seen', который вы тогда выбрасываете, не пользуясь быстрым поиском –

+1

Я согласен, я больше думал об использовании памяти, а не о сырой скорости. Я изменил его на набор, так что теперь он эффективнее и быстрее памяти :) –

+0

Да, набор имеет значение с большим входом. –

Смежные вопросы