Проверьте синтаксис URI пакета . Вы хотите что-то вроде этого:
Два простых способа выполнить просто фильтрацию:
Используя filter
:
names = filter(lambda name: name[-5:] != "Smith", names)
Используя понимания списка:
names = [name for name in names if name[-5:] != "Smith"]
Примечание, что оба случая сохраняют значения, для которых функция предиката оценивает к True
, таким образом, необходимо инвертировать логику (т.е. Вы говорите, "сохраняют людей, у которых нет фамилии, Smith" вместо "удаляет людей, у которых есть фамилия Smith").
Редактирование Забавный... два человека индивидуально отправили оба из ответов, которые я предложил, поскольку я отправлял мой.
Ну, это - ясно проблема со структурой данных, которую Вы используете. Используйте хеш-таблицу, например. Некоторые реализации поддерживают многократные въезды на ключ, таким образом, можно или вытолкать новейший элемент прочь, или удалять всех их.
, Но это, и что Вы собираетесь найти, что решение, элегантность через различную структуру данных, не алгоритм. Возможно, можно добиться большего успеха, если это отсортировано, или что-то, но повторение в списке является единственным методом здесь.
редактирование: каждый действительно понимает, что попросил 'эффективность'..., все эти предложенные методы просто выполняют итерации по списку, который совпадает с тем, что он предложил.
Фильтр и понимания списка хорошо для Вашего примера, но у них есть несколько проблем:
Ваше исходное решение на самом деле более эффективно для очень больших списков, даже если мы можем согласиться, что это более ужасно. Но если Вы волнуетесь, что у Вас могут быть несколько 'John Smith', это может быть зафиксировано путем удаления на основе положения а не на значении:
names = ['Jones', 'Vai', 'Smith', 'Perez', 'Smith']
toremove = []
for pos, name in enumerate(names):
if name[-5:] == 'Smith':
toremove.append(pos)
for pos in sorted(toremove, reverse=True):
del(names[pos])
print names
Мы не можем выбрать решение, не рассматривая размера списка, но для больших списков я предпочел бы Ваше решение с 2 передачами вместо фильтра или перечисляю понимания
Для ответа на вопрос о работе со словарями необходимо отметить, что Python 3.0 будет включать dict понимания :
>>> {i : chr(65+i) for i in range(4)}
Тем временем, можно сделать quasi-dict понимание этот путь:
>>> dict([(i, chr(65+i)) for i in range(4)])
Или как более прямой ответ:
dict([(key, name) for key, name in some_dictionary.iteritems if name[-5:] != 'Smith'])
Существуют времена, когда фильтрация (или использование фильтра или понимания списка) не работают. Это происходит, когда некоторый другой объект содержит ссылку на список, Вы изменяете, и необходимо изменить список на месте.
for name in names[:]:
if name[-5:] == 'Smith':
names.remove(name)
единственной разницей от исходного кода является использование names[:]
вместо names
в для цикла. Тем путем код выполняет итерации по (мелкой) копии списка и работы удалений как ожидалось. Так как список, копирующий, мелок, это довольно быстро.
Используя понимание списка
list = [x for x in list if x[-5:] != "smith"]
фильтр был бы потрясающим для этого. Простой пример:
names = ['mike', 'dave', 'jim']
filter(lambda x: x != 'mike', names)
['dave', 'jim']
Редактирование: понимание списка Corey является потрясающим также.
Можно также выполнить итерации назад по списку:
for name in reversed(names):
if name[-5:] == 'Smith':
names.remove(name)
Это имеет преимущество, что оно не создает новый список (как filter
или понимание списка) и использует итератор вместо копии списка (как [:]
).
Примечание, которое, хотя удаляя элементы при итерации назад безопасно, вставляя их, несколько более хитро.
names = filter(lambda x: x[-5:] != "Smith", names);
Оба решения, фильтр и понимание требуют создания нового списка. Я не знаю, что достаточно внутренностей Python уверено, но я думаю , что более традиционное (но менее изящный) подход могло быть более эффективным:
names = ['Jones', 'Vai', 'Smith', 'Perez']
item = 0
while item <> len(names):
name = names [item]
if name=='Smith':
names.remove(name)
else:
item += 1
print names
Так или иначе, для коротких списков, я придерживаюсь любого из этих двух решений, предложенных ранее.
В случае набора.
toRemove = set([])
for item in mySet:
if item is unwelcome:
toRemove.add(item)
mySets = mySet - toRemove