Ну, это решение было бы намного приятнее, если бы был способ вернуть список, меньший, чем первое вхождение данного элемента.
def remove1(lst, elem):
lst.remove(elem)
return lst
cpy = lst[:]
res = [x for x in lst if x not in del1 or x in remove1(cpy, x)]
Но это не будет работать, если в del1
есть повторяющиеся записи. Это будет работать,
res = [x for x in lst if x not in dlt or x in remove1(cpy, x) and x not in remove1(dlt, x)]
Но это становится смешным.
Полагаю, я оставлю свой ответ как доказательство того, что один вариант - плохая идея для этой проблемы.
So that users don't "have to remember to do the whole begin-rescue-ensure chacha" combine rescue
/ensure
with yield
.
class SomeResource
...
def SomeResource.use(*resource_args)
# create resource
resource = SomeResource.new(*resource_args) # pass args direct to constructor
# export it
yield resource
rescue
# known error processing
...
ensure
# close up when done even if unhandled exception thrown from block
resource.close
end
...
end
Client code can use it as follows:
SomeResource.use(connection_string) do | resource |
resource.do_something
... # whatever else
end
# after this point resource has been .close()d
In fact this is how File.open
operates - making the first answer confusing at best (well it was to my work colleagues).
File.open("testfile") do |f|
# .. process - may include throwing exceptions
end
# f is guaranteed closed after this point even if exceptions are
# thrown during processing
См. http://www.rubycentral.com/pickaxe/tut_exceptions.html
В Ruby Вы использовали бы ensure
оператор:
f = File.open("testfile")
begin
# .. process
rescue
# .. handle error
ensure
f.close unless f.nil?
end
Это будет знакомо пользователям Python, Java или C#, в котором он работает как попытка / выгода / наконец.
Как насчет yield
луг ресурс к блоку? Пример:
File.open("testfile") do |f|
begin
# .. process
rescue
# .. handle error
end
end