Цикличное выполнение через 2 Списка сразу

Проблема возникла из-за небольшой упущенной ситуации, когда текстовые файлы имели пропуски, поскольку список изображений был вырезан, скопирован и вставлен в один и тот же файл. Текстовые файлы были созданы в блокноте. В блокноте индекс не виден, но пропуски видны, когда вы просматриваете текстовые файлы в github, где первоначальное индексирование все еще присутствует, и индексирование остается, даже если размер списка был сокращен. Например, сначала был создан список из 182 изображений, но позже он был сокращен до 170. Поэтому, когда мы используем объект «Создание набора данных», код читает все строки текстового файла, т.е. он будет читать 182 вместо 170. Это повлияло на обучение модели. с набором данных, который был прочитан неправильно. Был создан новый набор текстовых файлов для train, val и test, и теперь обучение прошло правильно.

19
задан Graviton 28 October 2008 в 06:51
поделиться

5 ответов

[редактирование]: разъясниться; это полезно в универсальном LINQ / IEnumerable<T> контекст, где Вы не можете использовать индексатор, потому что a: это не существует на счетном, и b: Вы не можете гарантировать, что можно считать данные несколько раз. Так как OP упоминает лямбды, происходит, что LINQ не мог бы быть слишком далеко (и да, я действительно понимаю, что LINQ и лямбды являются не совсем тем же самым).

Это кажется на необходимость в пропавших без вести Zip оператор; можно имитировать его:

static void Main()
{
    int[] left = { 1, 2, 3, 4, 5 };
    string[] right = { "abc", "def", "ghi", "jkl", "mno" };

    // using KeyValuePair<,> approach
    foreach (var item in left.Zip(right))
    {
        Console.WriteLine("{0}/{1}", item.Key, item.Value);
    }

    // using projection approach
    foreach (string item in left.Zip(right,
        (x,y) => string.Format("{0}/{1}", x, y)))
    {
        Console.WriteLine(item);
    }
}

// library code; written once and stuffed away in a util assembly...

// returns each pais as a KeyValuePair<,>
static IEnumerable<KeyValuePair<TLeft,TRight>> Zip<TLeft, TRight>(
    this IEnumerable<TLeft> left, IEnumerable<TRight> right)
{
    return Zip(left, right, (x, y) => new KeyValuePair<TLeft, TRight>(x, y));
}

// accepts a projection from the caller for each pair
static IEnumerable<TResult> Zip<TLeft, TRight, TResult>(
    this IEnumerable<TLeft> left, IEnumerable<TRight> right,
    Func<TLeft, TRight, TResult> selector)
{
    using(IEnumerator<TLeft> leftE = left.GetEnumerator())
    using (IEnumerator<TRight> rightE = right.GetEnumerator())
    {
        while (leftE.MoveNext() && rightE.MoveNext())
        {
            yield return selector(leftE.Current, rightE.Current);
        }
    }
}
26
ответ дан 30 November 2019 в 03:03
поделиться

технический блог Senthil Kumar, имеет ряд, покрывающий реализации [1 114] (Python) Itertools для C#, включая itertools.izip .

От Itertools для C# - Цикл и Zip , у Вас есть решение для любого количества iterables (не только List< T> ). Обратите внимание что Zip урожаи Array на каждом повторении:

public static IEnumerable<T[]> Zip<T>(params IEnumerable<T>[] iterables)
{
IEnumerator<T>[] enumerators = Array.ConvertAll(iterables, (iterable) =>   iterable.GetEnumerator());

while (true)
{
   int index = 0;
   T[] values = new T[enumerators.Length];

   foreach (IEnumerator<T> enumerator in enumerators)
   {
       if (!enumerator.MoveNext())
          yield break;

        values[index++] = enumerator.Current;
   }

   yield return values;
}

}

код получает перечислители для всего iterables, перемещает все перечислители вперед, накапливает их текущие значения в массив и приводит к массиву. Это делает это, пока любой из перечислителей не исчерпывает элементы.

0
ответ дан 30 November 2019 в 03:03
поделиться

Я рекомендую использовать простой для цикла, но необходимо рассмотреть различные длины массива. Так

for(int i=0; i<ListA.Length; i++)
{
    Console.WriteLine(ListA[i].ToString() + ", " + ListB[i].ToString());
}

может превратиться

for(int i = 0; i < Math.Min(ListA.Length, ListB.Lenght); i++)
{
    Console.WriteLine(ListA[i].ToString() + ", " + ListB[i].ToString());
}

или даже в

    for(int i = 0; i < Math.Max(ListA.Length, ListB.Lenght); i++)
    {
        string valueA = i < ListA.Length ? listA[i].ToString() : "";
        string valueB = i < ListB.Length ? listB[i].ToString() : "";

        Console.WriteLine(valueA+ ", " + valueB);
    }
1
ответ дан 30 November 2019 в 03:03
поделиться

Можно сделать это явный.

IEnumerator ListAEnum = ListA.GetEnumerator();
IEnumerator ListBEnum = ListB.GetEnumerator();

ListBEnum.MoveNext();
while(ListAEnum.MoveNext()==true)
{
  itemA=ListAEnum.getCurrent();
  itemB=ListBEnum.getCurrent();
  Console.WriteLine(itemA.ToString()+","+itemB.ToString());
}

, По крайней мере, это (или что-то вроде этого) - то, что компилятор делает для цикла foreach. Я не протестировал его, хотя и я предполагаю, что некоторые шаблонные параметры отсутствуют для перечислителей.

Просто ищут GetEnumerator () из Списка и IEnumerator-интерфейса.

5
ответ дан 30 November 2019 в 03:03
поделиться

Будет намного более просто просто сделать это в простом для цикла вместо этого...

for(int i=0; i<ListA.Length; i++)
{
    Console.WriteLine(ListA[i].ToString() + ", " + ListB[i].ToString());
}
11
ответ дан 30 November 2019 в 03:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: