L oop над списком строк и выполнением задач (Введение в Python Упражнения Глава 2) - PullRequest
1 голос
/ 13 января 2020

где спросить, если мой код ясен и хорош. Итак, у меня есть три задачи:

enter image description here

Поэтому я попытался выполнить l oop и выполнить их все в одном l oop. Надеюсь получить отзыв, приятный.

names = ['mozzarella', 'cinderella', 'salmonella']
for i in range(len(names)):
  for name in names:
    if name == 'cinderella':
        names[i] = name.capitalize()
        i += 1
    elif name == 'mozzarella':
        names[i] = name.upper()
        i += 1
    elif name == 'salmonella':
        names.remove(name)

Вывод:

['MOZZARELLA', 'Cinderella']

Ответы [ 3 ]

1 голос
/ 13 января 2020

Есть несколько вещей, которые я бы сделал по-другому (поскольку вы спрашиваете о написании чистого кода, я обращаюсь к этому, а не только к функциональной точности). Как правило, при работе над проблемой, которая имеет различные проблемы, часто полезно разделять эти проблемы. В этом случае я не уверен, почему вы захотите управлять всеми 3 проблемами в пределах одной l oop. В программном обеспечении вы часто обнаруживаете, что одна проблема развивается с другой скоростью, чем другие проблемы. Кроме того, удаление элемента во время итерации по списку, как правило, не очень хорошая идея. Я бы использовал что-то вроде следующего:

def update_cheesy(name):
    if name == 'mozzarella':
        return name.upper()
    return name

def update_person(name):
    if name == 'cinderella':
        return name.capitelize()
    return name

names[:] = [update_person(name) for name in names]
print(names)
names[:] = [update_cheesy(name) for name in names]
print(names)
names[:] = [name for name in names if name != 'salmonella']
print(names)

Обратите внимание, что присваивание выполняется именам [:], а не именам. Это заменяет содержимое списка, а не просто устанавливает именованную ссылку на другой список.

Вы можете объединить все модификации в одном вызове, если считаете, что это чище.

1 голос
/ 13 января 2020

Здесь нет необходимости делать две итерации. Вы можете сделать один для range(), а затем вызвать список напрямую через names[i]. i - это текущая позиция в диапазоне, по которому она повторяется, поэтому, когда вы вызываете names[i], он вызывает этот индекс в списке.

for i in range(len(names)):
    if names[i] == 'mozzarella': 
        names[i] = names[i].upper()
    if names[i] == 'cinderella': 
        names[i] = names[i].capitalize()
    if names[i] == 'salmonella': 
        names.remove(names[i])

names
['MOZZARELLA', 'Cinderella']
0 голосов
/ 13 января 2020

Я думаю, что вы можете использовать python уменьшить здесь или просто forl oop

base_names = ['mozzarella', 'cinderella', 'salmonella']

# using forloop
result = []
for name in base_names:
    if name == 'salmonella':
        continue
    elif name == 'cinderella':
        name = name.capitalize()
    elif name == 'mozzarella':
        name = name.upper()
    result.append(name)
print(result)


# using reduce
from functools import reduce # for python3

def reduce_fuc(acc, name):
    if name == 'salmonella':
        return acc
    elif name == 'cinderella':
        name = name.capitalize()
    elif name == 'mozzarella':
        name = name.upper()
    acc.append(name)
    return acc

names = reduce(reduce_fuc, base_names, [])
print(names)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...