Подтвердить что ты не робот

Как я могу выполнять задания в понимании списка?

Я хочу использовать оператор присваивания в понимании списка. Как я могу это сделать?

Следующий код является недопустимым синтаксисом. Я хочу установить lst[0] в пустую строку '', если она соответствует pattern:

[ lst[0] = '' for pattern in start_pattern if lst[0] == pattern ]

Спасибо!

4b9b3361

Ответ 1

Похоже, вы путаете понимание списка с строками цикла в Python.

Понимание списка - список! Он не поддается одному назначению в существующем списке. (Хотя вы можете пытать синтаксис, чтобы сделать это...)

Пока не совсем ясно, что вы пытаетесь сделать из своего кода, я думаю, что он более похож на цикл по списку (управление потоком) против создания списка (понимание списка)

Прокрутите список таким образом:

for pattern in patterns:
   if lst[0] == pattern: lst[0]=''

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

if lst[0] in patterns: lst[0] = ''

Или, если вы не знаете индекс:

i=lst.index[pattern]
lst[i]=''

или, если у вас есть список списков и вы хотите изменить каждый первый элемент каждого подсписок:

for i, sublst in enumerate(lst):
    if sublst[i][0] in patterns: sublist[i][0]=''

и т.д. и т.д.

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

Лично я обычно предпочитаю больше использовать списки для создания списка:

 l=[[ x for x in range(5) ] for y in range(4)]  #init a list of lists...

Что более естественно, чем:

l=[]
for i in range(4):
   l.append([])
   for j in range(5):
      l[i].append(j)      

Но изменить тот же список списков, что более понятно?

Это:

l=[['new value' if j==0 else l[i][j] for j in range(len(l[i]))] for i in range(len(l))]

или это:

for i,outter in enumerate(l):
    l[i][0]='new value'               

YMMV

Здесь - отличный учебник по этому вопросу.

Ответ 2

Язык Python имеет различные понятия для выражений и операторов.

Назначение - это утверждение, даже если синтаксис иногда заставляет вас думать, что это выражение (например, a=b=99 работает, но является специальным случаем синтаксиса и не означает, что b=99 является выражением, например, в С).

Перечисления списков - это выражения, потому что они возвращают значение, в некотором смысле цикл, который они выполняют, является инцидентом, а основной точкой является возвращенный список.

Оператор может содержать выражения, но выражение не может содержать операторов.

Тем не менее, однако, атрибут элемента списка преобразован внутренне в вызов метода (для создания объектов, подобных списку), а вызовы методов - это выражения. Поэтому вы можете технически использовать назначение элементов списка в выражении:

[ lst.__setitem__(0, '') for pattern in start_pattern if lst[0] == pattern ]

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

for pattern in start_pattern:
    if lst[0] == pattern:
        lst[0] = ''

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

if lst[0] in start_pattern:
    lst[0] = ''

Перечисления списков используются для их возвращаемого значения, и они создают внутренний цикл... Если вам нужен цикл, тогда просто напишите цикл... тот, кто прочитает код, пытаясь понять, что он делает, (и кто бы ни включал себя через несколько недель).

Ответ 3

Вкратце: вы этого не делаете. Перечисления списков предназначены для создания списков, а не для изменения существующих списков. Если вы хотите изменить список, используйте цикл for, для чего они предназначены.

Питоновский способ написать этот код будет примерно таким:

for pattern in start_pattern:
    if lst[0] == pattern:
        lst[0] = ''
        #the following assumes that pattern will never be ''
        #if that possible, you can ignore this bit
        break

Однако, если вы действительно хотите сделать назначение внутри одного и не возражаете против каждого программиста на Python, который когда-либо сталкивался с вашим кодом, ненавидящим его на всю вечность, есть несколько функций, которые вы можете использовать:

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

        globals().update(var=value)
    
  • Если переменная, которую вы хотите назначить, является изменяемой последовательностью или картой (например, списком или dict)

        list.__setitem__(index, value)
    

Ответ 4

Если вы задаетесь вопросом:

[ lst[0] = '' for lst in listOfLists if lst[0] == pattern ]

или для списка моделей

[ lst[0] = '' for lst in listOfLists if lst[0] in patterns ]

Это на самом деле можно сделать легко

[ [''] + lst[1:] for lst in listOfLists if lst[0] == pattern ]

или для списка моделей снова

[[''] + lst[1:] for lst in listOfLists if lst[0] in patterns ]

Ответ 5

Python 3.8 представит выражения назначения.

Это новый символ:: := который позволяет присваивать (среди прочего) понимание.

Это принесет много потенциальной экономии по сравнению с вычислениями/памятью, как видно из следующего фрагмента вышеупомянутого связанного PEP (форматирование адаптировано для SO):

Синтаксис и семантика

В большинстве случаев, когда могут использоваться произвольные выражения Python, может появляться именованное выражение. Это имеет форму NAME := expr где expr - любое допустимое выражение Python, отличное от кортежа без скобок, а NAME - идентификатор.

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

  1. Обрабатывать подходящее регулярное выражение

    if (match := pattern.search(data)) is not None:
        # Do something with match
    
  2. Цикл, который нельзя переписать тривиально, используя 2-arg iter()

    while chunk := file.read(8192):
        process(chunk)
    
  3. Повторно использовать значение, которое дорого вычислять

    [y := f(x), y**2, y**3]
    
  4. Совместное использование подвыражения между предложением фильтра понимания и его выводом

    filtered_data = [y for x in data if (y := f(x)) is not None]
    

Это уже доступно в недавно выпущенной альфа-версии (не рекомендуется для производственных систем!). Вы можете найти расписание выпуска Python 3.8 здесь.