Как я уже упоминал в комментарии, я использовал словарь для решения этой проблемы.
Здесь вам не нужно беспокоиться о создании пустого списка с помощью какой-либо внешней функции, так как мы не знаем фактическую длину.
Так что вы можете попробовать вот так.
Вы можете посетить https://rextester.com/ZQKA28350 , чтобы запустить код онлайн.
blockquote>def add_words_to_bucket(words): d = {} for word in words: l = len(word) if l in d: d[l].append(word) else: i = 0 while l >= 0 and not l in d: if not i: d[l] = [word] else: d[l] = [] l = l - 1 i += 1 return d def get_as_list(d): bucket = [d[i] for i in range(0, len(d))] return bucket words = ["a", "git", "go", "py", "java", "paper", "ruby", "r"] d = add_words_to_bucket(words) bucket = get_as_list(d) print(d) # {0: [], 1: ['a', 'r'], 2: ['go', 'py'], 3: ['git'], 4: ['java', 'ruby'], 5: ['paper']} print(bucket) # [[], ['a', 'r'], ['go', 'py'], ['git'], ['java', 'ruby'], ['paper']] words2 = ["a", "git", "go", "py", "", "java", "paper", "ruby", "r","TheIpMan", ""] d2 = add_words_to_bucket(words2) bucket2 = get_as_list(d2) print(d2) # {0: ['', ''], 1: ['a', 'r'], 2: ['go', 'py'], 3: ['git'], 4: ['java', 'ruby'], 5: ['paper'], 6: [], 7: [], 8: ['TheIpMan']} print(bucket2) # [['', ''], ['a', 'r'], ['go', 'py'], ['git'], ['java', 'ruby'], ['paper'], [], [], ['TheIpMan']]
Если вы регистрируете исключение слишком близко к моменту его первого вызова, вы не будете регистрировать полную трассировку стека.
Обрабатывать исключения (то есть исправлять их) как можно ближе к тому моменту, когда они были сгенерированы. Соберите информацию о контексте как можно скорее, когда они были брошены. Но позвольте исключениям распространяться до того места, где они действительно могут быть обработаны. Ведение журнала - это последнее средство обработки, поэтому оно должно происходить на внешних уровнях подсистем приложения.
Это должно устранить необходимость в специфическом для приложения исключении, используемом в качестве маркера, чтобы не регистрировать исключение, которое не должно было быть обнаружено с самого начала.
Не регистрируйте исключение, а затем перебрасывайте его - это обязанность вызывающих абонентов обрабатывать / регистрировать любые сгенерированные исключения.
Только поймайте исключение, чтобы обработать его (например, чтобы зарегистрировать его), или добавьте специфичную для контекста информацию.
Первый вариант решения проблемы трассировки стека:
class AppSpecificException : ApplicationException
{
public string SpecificTrace { get; private set; }
public string SpecificMessage { get; private set; }
public AppSpecificException(string message, Exception innerException)
{
SpecificMessage = message;
SpecificTrace = innerException.StackTrace;
}
}
Мне пришлось написать пример, чтобы понять вопрос и проверить проблему трассировки стека, это код мне, обратите внимание на метод button2_click, наконец, в моем текстовом поле отображается строка сбоя и трассировка стека:
private String internalValue;
private void Operation1(String pField)
{
if (pField == null) throw new ArgumentNullException("pField");
internalValue = pField;
}
private void Operation2(Object pField)
{
if (pField == null) throw new ArgumentNullException("pField");
internalValue = Convert.ToInt32(pField).ToString();
}
private void Operation3(String pField)
{
if (pField == null) throw new ArgumentNullException("pField");
internalValue = pField;
Operation2(-1);
}
/// <exception cref="AppSpecificException"><c>AppSpecificException</c>.</exception>
private void button1_Click(object sender, EventArgs e)
{
try
{
Operation1("One");
Operation2("Two");
Operation3("Three");
MessageBox.Show(internalValue);
}
catch (ArgumentNullException ex)
{
textBoxException.Text = ex.Message + (char) 13 + (char) 10 + ex.StackTrace;
}
catch (AppSpecificException ex)
{
//textBoxException.Text = ex.Message + (char)13 + (char)10 + ex.StackTrace;
throw;
}
catch (Exception ex)
{
textBoxException.Text = ex.Message + (char)13 + (char)10 + ex.StackTrace;
throw new AppSpecificException("crash", ex);
}
}
private void button2_Click(object sender, EventArgs e)
{
try
{
button1_Click(sender, e);
}
catch (AppSpecificException ex)
{
textBoxException.Text = ex.SpecificMessage + (char) 13 + (char) 10 + ex.SpecificTrace;
}
}
Я бы рекомендовал больше подумать о том, какие шаблоны вы хотите использовать для " handing "
Если ваши шаблоны обработки сводятся к журналированию или повторному вызову, то в конечном итоге повторная ошибка будет записана в журнал. Так что, в конце концов, это просто регистрация ошибок. Если вы используете ASP.NET, используйте elmah, чтобы, по крайней мере, ваш код не был покрыт котельной плитой try / catch-and-log.
Есть только несколько способов «обработать» ошибки, которые не заканчиваются простой регистрацией.
Повторите попытку. (Остерегайтесь бесконечных циклов)
Подождите и попробуйте еще раз.
Попробуйте другой, но эквивалентный метод (Не удается подключиться по http? Попробуйте подключиться по https).
Установите недостающие условия (создайте папку, в которой возникло исключение FolderNotFoundException)
Игнорируйте ошибку - подумайте дважды, это имеет смысл только тогда, когда ошибка на самом деле не является проблемой, например, если есть сторонняя библиотека предупреждает вас о неприменимом условии.
Это довольно распространенный подход к решению проблемы обработки исключений (от более конкретного к менее конкретному).
Только имейте в виду, что иметь одно общее исключение ApplicationSpecific для перехвата всего, что происходит в данном приложении/методе - не лучшая идея, если вы хотите отлавливать специфические проблемы. В конце концов, попробуйте расширить его более специфическими исключениями.
Перебрасывание исключений - это хорошо, но лучше объявить метод, который будет перебрасывать определенные исключения, и позволить вызывающим пользователям обрабатывать их. Таким образом, вам придется создавать меньше кода, и вы сможете централизовать некоторые элементы управления.
Хорошим решением для обработки исключений является использование перехвата.Однако вы должны проверить, можно ли применить этот шаблон к вашему приложению в зависимости от архитектуры: для перехвата требуется контейнер.
Принцип состоит в том, чтобы факторизовать обработку исключений вне методов, используя для них атрибуты (настраиваемые), а затем использовать контейнер для инициализации ваших экземпляров. Контейнер будет проксировать эти экземпляры путем отражения: вызываемые им экземпляры-перехватчики. Вам просто нужно будет вызывать свои методы как обычно через экземпляры тезисов и позволить механизму перехвата выполнять работу, которую вы закодировали до или после метода.
Обратите внимание, что вы можете добавить try catch в методы управления конкретными исключениями, которые не обрабатываются в ваших перехватчиках.
Перехват Unity: http://msdn.microsoft.com/en-us/library/dd140045.aspx
Старайтесь избегать создания нового исключения и повторной генерации исключения, поскольку генерирование исключения устанавливает трассировку стека в то место, где возникло исключение. Просто сделайте простой бросок. См. Too Much Reuse в блоге Эрика Липперта.