Предыдущее решение: Как заявил Martijn Pieters, правильный и самый быстрый формат:
if 1 in {x, y, z}:
Одна из основных проблем, которая, похоже, не рассматривается, заключается в том, что вы хотите, чтобы ваш выходной список включают каждое письмо после утверждения if. Используя только совет Martijn Pieters, у вас теперь будет:
if 0 in {x, y, z}:
Mylist.append("c")
elif 1 in {x, y, z}:
Mylist.append("d")
...
Проблема: первый оператор if вернет true, и вы никогда не получите следующий оператор elif. Таким образом, ваш список просто вернется:
["c"]
. Вы хотите иметь отдельные операторы if, чтобы python прочитал каждое утверждение, были ли первые правильными или ложными. Например:
if 0 in {x, y, z}:
Mylist.append("c")
if 1 in {x, y, z}:
Mylist.append("d")
if 2 in {x, y, z}:
Mylist.append("e")
...
Это будет работать, но «если» вам удобно использовать словари (см. То, что я там сделал), вы можете очистить это, сделав исходный словарь, сопоставляющий числа с буквами вы хотите, а затем просто используйте цикл 'for':
numToLetters = {0:"c", 1:"d", 2:"e", 3:"f"}
for number in numToLetters:
if number in {x, y, z}:
Mylist.append(numToLetters[number])
Фактическая проблема заключается в том, что вы сравниваете два long[]
, а Enumerable.SequenceEquals
будет использовать ObjectEqualityComparer<Int64[]>
(вы можете видеть, что, исследуя EqualityComparer<long[]>.Default
, который является тем, что внутренне используется Enumerable.SequenceEquals
), который будет сравнивать ссылки этих двух массивов, а не фактические значения , хранящиеся внутри массива, которые, очевидно, не совпадают.
Чтобы обойти это, вы могли бы напишите EqualityComparer<long[]>
:
static void Main()
{
var expected = new List<long[]>
{ new[] { Convert.ToInt64(1), Convert.ToInt64(999999) } };
var actual = DoSomething();
if (!actual.SequenceEqual(expected, new LongArrayComparer()))
throw new Exception();
}
public class LongArrayComparer : EqualityComparer<long[]>
{
public override bool Equals(long[] first, long[] second)
{
return first.SequenceEqual(second);
}
// GetHashCode implementation in the courtesy of @JonSkeet
// from http://stackoverflow.com/questions/7244699/gethashcode-on-byte-array
public override int GetHashCode(long[] arr)
{
unchecked
{
if (array == null)
{
return 0;
}
int hash = 17;
foreach (long element in arr)
{
hash = hash * 31 + element.GetHashCode();
}
return hash;
}
}
}
SequenceEquals
тесты для идентичности элементов внутри последовательностей. Элементы в перечислениях имеют тип long[]
, поэтому мы фактически сравниваем два разных массива (содержащих одни и те же элементы) друг против друга, что наглядно сделано путем сравнения их ссылок вместо их фактического значения.
Итак, что мы на самом деле проверяем здесь, это expected[0] == actual[0]
вместо expected[0].SequqnceEquals(actual[0])
Это obiosuly возвращает false
, поскольку оба массива используют разные ссылки.
Если мы сглаживаем иерархию с помощью SelectMany
, получаем то, что хотим:
if (!actual.SelectMany(x => x).SequenceEqual(expected.SelectMany(x => x))) throw new Exception();
EDIT:
На основе этот подход нашел другое элегантное способ проверить, содержатся ли все элементы из expected
в actual
:
if (!expected.All(x => actual.Any(y => y.SequenceEqual(x)))) throw new Exception();
Это будет поиск, если на вечном суб-списке внутри expected
есть список внутри actual
который последовательно идентичен текущему. Это кажется гораздо умнее, так как нам не нужны никакие пользовательские EqualityComparer
и не странные хэш-код-реализация.
Нет, ваши последовательности not равны!
Позволяет удалить бит последовательности и просто взять то, что находится в первом элементе для каждого элемента
var firstExpected = new[] { Convert.ToInt64(1), Convert.ToInt64(999999) };
var firstActual = new[] { Convert.ToInt64(1), Convert.ToInt64(999999) };
Console.WriteLine(firstExpected == firstActual); // writes "false"
Приведенный выше код сравнивает два отдельных массива для равенства. Равенство не проверяет содержимое массивов, проверяет ссылки на равенство.
Ваш код с использованием SequenceEquals
, по сути, делает то же самое. Он проверяет ссылки в каждом случае каждого элемента в перечислимом.