Как @AaronHall, я попал сюда в поисках кусков примерно одинакового размера. Есть разные интерпретации этого. В моем случае, если желаемый размер N, я бы хотел, чтобы каждая группа имела размер> = N. Таким образом, сироты, созданные в большинстве из вышеперечисленного, должны быть перераспределены на другие группы.
Это можно сделать, используя:
def nChunks(l, n):
""" Yield n successive chunks from l.
Works for lists, pandas dataframes, etc
"""
newn = int(1.0 * len(l) / n + 0.5)
for i in xrange(0, n-1):
yield l[i*newn:i*newn+newn]
yield l[n*newn-newn:]
(из Разделение списка на N частей приблизительно равной длины ), просто назвав его nChunks (l, l / n). ) или nChunks (л, пол (л / н))
Эта проблема возникает, когда функция сравнения несовместима, так что x Вот пример, который воспроизводит проблему. Здесь это вызвано патологической функцией сравнения compareStrings. Это зависит от начального состояния списка: если вы измените начальный порядок на «C», «B», «A», то исключений не будет. Я бы не назвал это ошибкой в функции сортировки - это просто требование согласованности функции сравнения. using System.Collections.Generic;
class Program
{
static void Main()
{
var letters = new List<string>{"B","C","A"};
letters.Sort(CompareStrings);
}
private static int CompareStrings(string l, string r)
{
if (l == "B")
return -1;
return l.CompareTo(r);
}
}
Вы уверены, что проблема не в том, что SomeProp
равен null
?
В частности, со строками или Nullable
значений.
Для строк было бы лучше использовать:
list.Sort((x, y) => string.Compare(x.SomeProp, y.SomeProp));
(edit)
Для нулевой безопасной оболочки вы можете использовать Comparer
- например, чтобы отсортировать список по свойству:
using System;
using System.Collections.Generic;
public static class ListExt {
public static void Sort<TSource, TValue>(
this List<TSource> list,
Func<TSource, TValue> selector) {
if (list == null) throw new ArgumentNullException("list");
if (selector == null) throw new ArgumentNullException("selector");
var comparer = Comparer<TValue>.Default;
list.Sort((x,y) => comparer.Compare(selector(x), selector(y)));
}
}
class SomeType {
public override string ToString() { return SomeProp; }
public string SomeProp { get; set; }
static void Main() {
var list = new List<SomeType> {
new SomeType { SomeProp = "def"},
new SomeType { SomeProp = null},
new SomeType { SomeProp = "abc"},
new SomeType { SomeProp = "ghi"},
};
list.Sort(x => x.SomeProp);
list.ForEach(Console.WriteLine);
}
}
Ответ Марка полезен. Я согласен с ним, что NullReference возникает из-за вызова CompareTo для нулевого свойства. Без класса расширения вы можете:
mylist.Sort((x, y) =>
(Comparer<SomePropType>.Default.Compare(x.SomeProp, y.SomeProp)));
, где SomePropType - это тип SomeProp
В целях отладки вы хотите, чтобы ваш метод был нулевым. (или, по крайней мере, перехватить исключение null-ref. и обработать его жестко запрограммированным способом). Затем используйте отладчик, чтобы посмотреть, какие другие значения сравниваются, в каком порядке и какие вызовы завершаются успешно или неуспешно.
Тогда вы найдете свой ответ и сможете удалить нулевую безопасность.
Можете ли вы запустить этот код ...
mylst.Sort((i, j) =>
{
Debug.Assert(i.SomeProp != null && j.SomeProp != null);
return i.SomeProp.CompareTo(j.SomeProp);
}
);
Я сам наткнулся на эту проблему и обнаружил, что она связана со свойством NaN
в моем вводе. Вот минимальный тестовый пример, который должен вызвать исключение:
public class C {
double v;
public static void Main() {
var test =
new List<C> { new C { v = 0d },
new C { v = Double.NaN },
new C { v = 1d } };
test.Sort((d1, d2) => (int)(d1.v - d2.v));
}
}