2017-01-08 3 views
4

Две версии, возвращают противоположные ответы, но всегда один выходит неправильно. Я не знаю, где я ошибся. Я пробовал ряд других вариантов, но, похоже, это ближе всего. EDIT: Нужно быть в циклеПроблема с итерацией питона

цели: определить элемент в списке, определить, когда элемент не находится в списке, определить, когда список [], возвращать строки соответственно.

def search_for_string(a_list, search_term): 
    i=0 
    for search_term in a_list: 
     i += 1 
     if a_list[i] == search_term: 
      return 'string found!' 
     elif a_list[i] != search_term: 
      return 'string not found2' 
    if len(a_list) == 0: 
     return 'string not found' 

apple = search_for_string(['a', 'b', 'c'], 'd') 
print(apple) 


def search_for_string(a_list, search_term): 
    i=0 
    for search_term in a_list: 
     if a_list[i] == search_term: 
      return 'string found!' 
     elif a_list[i] != search_term: 
      return 'string not found2' 
     i += 1 
    if len(a_list) == 0: 
     return 'string not found' 

apple = search_for_string(['a', 'b', 'c'], 'd') 
print(apple) 

другие испытания:

apple = search_for_string(['a', 'b', 'c'], 'b') 
apple = search_for_string([], 'b') 
+2

Прежде всего, вы переписываете значение переменной search_term. Например, вы передаете его как «d», но оно будет перезаписано, потому что ваш цикл for использует одно и то же имя переменной. Чтобы узнать, что происходит, попробуйте напечатать значение search_term внутри цикла for. (т. е. добавить 'print (search_term)' как строку под первой строкой цикла for.) Это может помочь вам отладить. –

+0

Я понимаю, что вы имеете в виду, но я не знаю, что с этим делать. Хаха, я буду продолжать беспорядок. – Megan

+0

Возможно, вы захотите посмотреть 'enumerate().' Он сохранит вам объект 'i'. – boardrider

ответ

8

Python делает вашу жизнь очень легко для такого рода вещи:

def search_for_string(a_list, search_term): 
    if search_term in a_list: 
     return 'string found!' 
    return 'string not found' 
2

Короткий ответ, что возвращение к != не делать то, что вы думаете, что делает и что списки 0-проиндексированы не 1-индексироваться. Код на самом деле гораздо проще, чем вы думаете:

def search_for_string(haystack, needle): 
    if not haystack: # check for empty list 
     return 'List was empty!' 
    for x in haystack: 
     if needle == x: 
      return 'String found!' 
    return 'String not found!' 

По существу, вы знаете только, если строка не была найдена, если вы прошли и проверили каждый элемент, по меньшей мере один раз. Но вы знаете, была ли найдена строка, ну, когда вы ее найдете.


Теперь, чтобы объяснить проблемы с вашим кодом:

  1. Эта версия не работает, потому что (1) он пропускает первый элемент в списке и (2) возвращает строку не найден/найдены только после проверки первого элемента:

    def search_for_string(a_list, search_term): 
        i=0 
        for search_term in a_list: 
         i += 1 
         if a_list[i] == search_term: # whoops this comparison checks for succeeding elements! 
          return 'string found!' 
         elif a_list[i] != search_term: # whoops this part returns even before all succeeding elements are checked. 
          return 'string not found2' 
        if len(a_list) == 0: 
         return 'string not found' 
    
    apple = search_for_string(['a', 'b', 'c'], 'd') 
    # In the list ['a', 'b', 'c'] 
    # element [0] = 'a' 
    # element [1] = 'b' 
    # element [2] = 'c' 
    print(apple) 
    

Чтобы объяснить немного дальше давайте этот шаг за шагом через йо ур код:

# search_term == 'd' 
# a_list = [ 'a', 'b', 'c' ] 
i = 0 # at this point i == 0 
for search_term in a_list: 
    # Oh no! we lost the search term that we passed into the 
    # function because we are using it as the loop iterator 
    # search_term == 'a' 
    i += 1 # i == 1 
    if a_list[i] == search_term: 
     # checks to see if 'b' == 'a' 
     return 'string found!' 
    elif a_list[i] != search_term: 
     # checks to see if 'b' != 'a' 
     return 'string not found!' 
     # and we return after one iteration of the loop. 

Ваша вторая версия имеет ту же задачу (1) (2), но избегает этого вопроса, где первый элемент не проверяется.

+1

'' 'if needle == haystack''' ->' '' if needle == x'''? – wwii

+0

Спасибо, что поймали это. – 2ps

+0

Да, это работает. Извините Забыл упомянуть попытку сделать это внутри цикла. – Megan

1

В вашей функции search_for_string есть много чего не так.

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

Вот простейшая версия вашей функции, и она отвечает всем вашим требованиям.

def search_for_string(a_list, search_item): 
    if(len(a_list) == 0): 
     return 'List is empty' 
    else: 
    for search_term in a_list: 
     if search_term == search_item: 
      return 'string found!' 
    return 'string not found' 
3

Есть несколько вещей неправильно и Non-вещий в вашем коде:

def search_for_string2(a_list, search_term): 
    i=0 # <----- Not Pythonic! If you want to get index we use enumerate(a_list) 
    for search_term in a_list: # <--- search_term passed to function is lost and gets overwritten by elements in a_list. 
     i += 1 # <--- Not Pythonic in this context 
     if a_list[i] == search_term: #<--- a_list[index+1] == a_list[index]. True if consecutive elements are same else False! 
      return 'string found!' #<--- No WRONG!, You didn't find the string, Consecutive elements are same! 
     elif a_list[i] != search_term: 
      return 'string not found2' #<-- Consecutive elements are not same! 
    if len(a_list) == 0: 
     return 'string not found' 

Согласно для целей, которые вы определили, вы можете реализовать его так:

def search_for_string(alist, search_term): 
    if not alist: 
     return "List is empty" 
    if search_term in alist: 
     return "First occurence of string Found at index position: " + str(alist.index(search_term)) 
    else: 
     return "String not found" 


print(search_for_string(['a', 'b', 'c'], 'd')) 
print(search_for_string(['a', 'b', 'c'], 'b')) 
print(search_for_string([], 'b')) 

Выход:

String not found 
First occurence of string Found at index position: 1 
List is empty 
1

У вас есть довольно много ошибок в коде в. Некоторые из них важны, другие - нет. Попробую обратиться к ним:

  • Вы получили переменную search_term в качестве аргумента функции, но затем перезаписать значение его, используя его в ваш цикл.
  • Вы выполняете итерацию по a_list по значению, но затем пытаетесь использовать переменную цикла i для итерации по индексу. Не делай этого. Вы уже итерируете по значению, вам не нужно делать то и другое.
  • Вы пытаетесь проверить, если a_list пуст на конце вашей функции. Сделайте вначале. Еще лучше, выровняйте оператор if и просто возвращайтесь в конце своей функции. Цикл for не будет запущен, если a_list пуст.

Теперь, вот как я бы переписать функцию:

>>> def search_for_string(lst, key): 
    # only iterate by value. 
     for string in lst: 
      # we only need to test once 
      # if `key` is equal to the 
      # current string we are on. 
      if string == key: 
       return 'string found' 
     # no need to test if the list 
     # is empty. The for loop will 
     # never be run if it is, and 
     # this return statement will 
     # execute. 
     return 'string not found' 

>>> search_for_string(['a', 'b', 'c'], 'd') 
'string not found' 
>>> search_for_string(['a', 'b', 'c'], 'b') 
'string found' 
>>> search_for_string([], 'b') 
'string not found' 
>>> 
1

Для вашего кода, следует иметь в виду, что вы не ищете должным образом. Вы проходите в search_term, но переменная в for x in y устанавливает x равным значению следующего элемента в y. Поэтому, если у вас есть for x in [1, 2, 3], при первом запуске он установит x = 1 и т. Д. Таким образом, первая функция будет проверять, есть ли 'a' == 'b', что это не так, а вторая функция будет проверять, является ли 'a' = = 'a', что и есть, но это не то, что вы ищете!

Лучший способ найти, если элемент находится в списке

x in list 

это будет возвращать истинным или ложным, если х в списке или нет! (не используйте переменную «list», хотя это плохая практика, поскольку она скрывает встроенную функцию).

Так более Pythonic способ сделать это было бы

def search_for_string(a_list, search_term): 
    if search_term in a_list: 
     return 'string found!' 
    elif not a_list: # realistically you'd put this before here but I'm trying to mirror your code--why might you put this earlier? Because it's less costly than searching a list. 
     return 'empty list!' 
    else: 
     return 'string not found!' 

Также отметим, что bool([]) возвращает значение False, которое, как мы проверяем, если список пуст.

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

def search_for_string(a_list, search_term): 
    for index, item in enumerate(a_list): 
     if a_list[index] == search_term: 
      return 'string found!' 
      # what do you think the value of 'item' is here? it's equal to a_list[index]! 
     elif len(a_list) == 0: # again, you'd put this earlier--why make your computer do the work? it doesn't have to. Also, you could just do elif not a_list 
      return 'string not found' 
     else: 
      continue 
    return 'string not found2' 
1

Большинство вопросов, имеющих отношение к коду, рассматриваются в предыдущих ответах здесь, и ответ дается @Stephen Раух суммирует наиболее Pythonic подход к вашей проблеме.

Есть еще одна вещь, которая заставляет ваш код не делать то, что вы делаете, даже если все остальное было правильным.

Когда вы входите в функцию, вы эффективно выходите из этой функции.

Итак, эффективно, используя подход петли for, который вы пытались выполнить, вы будете проверять только первое значение в a_list, возвращая «Найденный», если он соответствует вашим критериям поиска, и возвращает «Не найден», если первый значение не соответствует вашим критериям поиска, а затем выходит из вашей функции.

По существу, вы никогда не будете проверять значение выше первого значения.

1

Прежде всего, разница в вашем первом методе и втором методе увеличивает i до и после выполнения инструкции if. Если вы сначала увеличиваете i, ваш цикл не найдет значение для первого элемента списка. вы используете i в качестве приращения, но это не нужно в python. Вы можете просто узнать, используя ли элемент в списке.

def search_for_string(a_list, search_term): 

    #if a_list is empty, return False 
    if len(a_list) == 0: 
      return False 
    #if search_term has an element in a_list return the string 
    if search_term in a_list: 
      return "string found" 

    return "string not found" 
Смежные вопросы