2013-05-08 5 views
0

Я довольно новичок в Python. Imagine У меня есть список [100, 200, 300, 301, 315, 345, 500]. Я хочу создать из него новый список, например [100, 200, 300, 500].Итерация через список для

Когда я итерацию по списку, как, что:

for i in range(len(list)): 
    while (list[i+1] - 100) <= list[i]: 
     i = i + 1 
     k = list[i] 

Затем изменения i внутри время цикла не отражены на i в течение цикла, так что итерации несколько раз через те же элементы.

Что было бы лучшим способом изменить код, чтобы этого избежать?

ответ

5

Вот как я это сделать

>>> mylist = [100,200,300,301,315,345,500] 
>>> [x for x in mylist if x % 100 == 0] 
[100, 200, 300, 500] 

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

def my_filter(lst): 
    ret = [lst[0]] 
    for i1, i2 in zip(lst, lst[1:]): 
     if i2 - i1 >= 100: 
      ret.append(i2) 
    return ret 

выше алгоритм работает следующим образом:

>>> my_filter([101, 202, 303, 305, 404, 505]) 
[101, 202, 303, 505] 
1

range(len(list)) будет просматривать длину списка один раз, а затем создать из него диапазон-итератор, который затем полностью отделен от списка и его длины.

Так for i in range(len(list)) заставит i идти от 0 к len(list)-1, без соблюдения изменений списка. Также обратите внимание, что обновление переменной итератора i внутри цикла никак не повлияет на сам цикл. Когда начнется следующая итерация, i просто получит следующее значение, независимо от того, хотите ли вы пропустить интеркацию, увеличивая до i.

Чтобы пропустить итерации, вы обычно используете оператор continue, который просто прервет текущую итерацию и начнет со следующего i.

В отношении вашей реальной проблемы вы, кажется, хотите отфильтровать все числа, кратные 100. Вы можете проверить, что для одного номера намного проще, проверяя, можете ли вы разделить его на 100 без каких-либо остатков. Для этого вы используете modulo operation, который даст вам остаток для деления. В сочетании с пониманием список, в котором вы отфильтровывать для тех, вы можете написать его просто так:

>>> lst = [100, 200, 300, 301, 315, 345, 500] 
>>> [n for n in lst if n % 100 == 0] 
[100, 200, 300, 500] 

Также обратите внимание, что вы не должны называть переменные list как перезаписывает ссылку на list типа.

+0

Спасибо за ответ, но на самом деле моя цель является немного более сложным. Список был всего лишь примером. Извините, за то, что вы были неточными, но я не хотел вдаваться в подробности и давать слишком сложное описание. У меня есть несколько скользящих окон, а два списка сохраняют начальную и конечную позиции для каждого окна. Я хочу отфильтровать перекрывающиеся или соседние окна.Когда следующий элемент в списке очень близок к предыдущему, я хочу выполнить итерацию по списку, пока не найду элемент, который достаточно далеко, как только я его найду, я могу получить доступ к соответствующему элементу из второго списка. – Malfet

0

Вот мое решение:

def my_filter(xs): 
    ys = [] 
    for x in xs: 
     if (not ys) or ys[-1] + 100 <= x: 
      ys.append(x) 
    return ys 
my_filter([100, 200, 300, 301, 315, 345, 500]) >> [100, 200, 300, 500] 
+0

Обратите внимание, что на некоторых входах этот алгоритм производит другой результат, чем мой. Например, для ввода '[100, 150, 200]' ваша функция выводит '[100, 200]', в то время как моя производит '[100]'. Я не уверен, что OP действительно хотел, хотя, поскольку вход и выход, которые он выбрал, соответствуют всем трем алгоритмам, данным до сих пор в этих ответах. –

+0

Спасибо, за ваш ответ. Дело в том, что мне понадобится также индекс для каждого элемента. Итак, в моем примере, как только я перехожу через 301 315 345 и нахожу 500, я должен получить соответствующий 6-й элемент из другого списка ... и, да, мне тоже нужно последнее значение. – Malfet

+0

@Malfet Вы можете использовать 'enumerate', чтобы получить как элемент, так и его индекс. – poke

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