2014-12-10 3 views
6

Я пытаюсь научиться аккуратно вещий способы делать вещи, и было интересно, почему мой цикл не может быть переработан таким образом:Инлайн цикл

q = [1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5] 
vm = [-1, -1, -1, -1] 

for v in vm: 
    if v in q: 
     p.append(q.index(v)) 
    else: 
     p.append(99999) 

vm[p.index(max(p))] = i 

Я попытался заменить для цикла с:

[p.append(q.index(v)) if v in q else p.append(99999) for v in vm] 

Но это не работает. Цикл for v in vm: выдает номера от vm на основе того, когда они будут следующими в q.

+0

Вы можете захотеть использовать - 1 вместо 99999 для отметки несуществующего значения (так что это будет работать даже для списка с элементами 99999+) –

+0

вы перечислите comprehsnsion, но он вернет списки None too – Hackaholic

+0

Я использовал 99999 вместо -1, потому что позже я побежал следует выбрать max (p) и несуществующие значения. – Will

ответ

10

В Python вы используете list comprehension, а не встроенный for-loop (хотя он похож на один). Вы бы написать свой цикл в виде списка понимания, как так:

p = [q.index(v) if v in q else 99999 for v in vm] 

При использовании списка понимания, вы не вызываете list.append, потому что список строится из самого понимания. Каждый элемент в списке будет тем, что возвращается выражением слева от ключевого слова for, которое в этом случае равно q.index(v) if v in q else 99999. Кстати, если вы используете list.append внутри понимания, тогда вы получите список значений None, потому что это всегда возвращает метод append.

+0

Спасибо, мужчина, здорово!+ интернетов для ответа менее чем за минуту. – Will

2

вы можете использовать enumerate сохраняя IND/индекс элементов в виртуальной машине, если вы сделаете vmset вы также будете иметь 0(1) Lookups:

vm = {-1, -1, -1, -1} 

print([ind if q in vm else 9999 for ind,ele in enumerate(vm) ]) 
+0

Прохладный причудливый синтаксис, спасибо за совместное использование этого взгляда очень полезно! – Will

2

ваш список comphresnion сможет работать, но будет возвращать список из None, потому что возвращение Append None:

демо:

>>> a=[] 
>>> [ a.append(x) for x in range(10) ] 
[None, None, None, None, None, None, None, None, None, None] 
>>> a 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

лучший способ, чтобы использовать это нравится:

>>> a= [ x for x in range(10) ] 
>>> a 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
1
q = [1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5] 
vm = [-1, -1, -1, -1,1,2,3,1] 

p = [] 
for v in vm: 
    if v in q: 
     p.append(q.index(v)) 
    else: 
     p.append(99999) 

print p 
p = [q.index(v) if v in q else 99999 for v in vm] 
print p 

Выход:

[99999, 99999, 99999, 99999, 0, 1, 2, 0] 
[99999, 99999, 99999, 99999, 0, 1, 2, 0] 

Вместо использования append() в списке понимания вы можете ссылаться на р, как прямой выход, а также использовать q.index(v) и 99999 в ЛК.

Не уверен, что это преднамеренно, но обратите внимание, что q.index(v) найдет только первое появление v, даже у вас есть несколько в q. Если вы хотите, чтобы получить индекс всех v в q, рассмотреть вопрос об использовании enumerator и список уже посетили indexes

Что-то в этих строках (псевдо-код):

visited = [] 
for i, v in enumerator(vm): 
    if i not in visited: 
     p.append(q.index(v)) 
    else: 
     p.append(q.index(v,max(visited))) # this line should only check for v in q after the index of max(visited) 
    visited.append(i)