Подскажите как быстро соединить две отсортированные коллекции
привет
есть штук 10 коллекций объектов отсортированных по полю datatime
суммарное количество элементов — 30 000 000
подскажите как быстрее всего собрать из этих коллекций в одну — отсортированную по этому же полю
Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Как быстро соединить много csv Файлов?
Как быстро соединить много csv Файлов? Данных в таблицах много, но количество столбцов одинаково.
Как наиболее быстро соединить все слова в одну строку через запятую?
Как по бистрому соеденить все слова в одну строку через кому? (можно через контатенацию) Слова.
Как соединить две программы?
Помогите плиз, подскажите как соединить 2 программы
как соединить две линии в одну
мне нужно написать программу, которая соединяет две выбранные линии в одну: начальную точку первой.
![]()
17413 / 12809 / 3355
Регистрация: 17.09.2011
Сообщений: 21,087

Сообщение было отмечено saderty как решение
Решение
Сообщение от saderty 
есть штук 10 коллекций объектов отсортированных по полю datatime
суммарное количество элементов — 30 000 000
Суровые размеры, зачем с такими в памяти работать?
Если повезет и приложение не закрашится из-за нехватки памяти, то вот общий вариант для любого типа коллекций:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
static IEnumerableT> MergeT>(IEnumerableIEnumerableT>> collections, IComparerT> comparer = null) { if (comparer == null) comparer = ComparerT>.Default; var result = new ListT>(); var iters = new ListIEnumeratorT>>(); foreach (var collection in collections) { var iter = collection.GetEnumerator(); if (iter.MoveNext()) iters.Add(iter); else iter.Dispose(); } while (iters.Count > 0) { var min = iters[0]; for (int i = 1; i iters.Count; i++) { if (comparer.Compare(iters[i].Current, min.Current) 0) min = iters[i]; } result.Add(min.Current); if (!min.MoveNext()) { iters.Remove(min); min.Dispose(); } } return result; }
Если коллекции всегда одного известного типа, то можно написать специализированный метод, в который включить некоторые оптимизации.
Как объединить две коллекции c
LINQ предоставляет несколько методов для работы с коллекциями как с множествами, а именно находить их разность, объединение и пересечение.
Разность последовательностей
С помощью метода Except() можно получить разность двух последовательностей:
string[] soft = < "Microsoft", "Google", "Apple">; string[] hard = < "Apple", "IBM", "Samsung">; // разность последовательностей var result = soft.Except(hard); foreach (string s in result) Console.WriteLine(s);
В данном случае из массива soft убираются все элементы, которые есть в массиве hard . Результатом операции будут два элемента:
Microsoft Google
Пересечение последовательностей
Для получения пересечения последовательностей, то есть общих для обоих наборов элементов, применяется метод Intersect :
string[] soft = < "Microsoft", "Google", "Apple">; string[] hard = < "Apple", "IBM", "Samsung">; // пересечение последовательностей var result = soft.Intersect(hard); foreach (string s in result) Console.WriteLine(s);
Так как оба набора имеют только один общий элемент, то соответственно только он и попадет в результирующую выборку:
Apple
Удаление дубликатов
Для удаления дублей в наборе используется метод Distinct :
string[] soft = < "Microsoft", "Google", "Apple", "Microsoft", "Google" >; // удаление дублей var result = soft.Distinct(); foreach (string s in result) Console.WriteLine(s);
Microsoft Google Apple
Объединение последовательностей
Для объединения двух последовательностей используется метод Union . Его результатом является новый набор, в котором имеются элементы, как из первой, так и из второй последовательности. Повторяющиеся элементы добавляются в результат только один раз:
string[] soft = < "Microsoft", "Google", "Apple">; string[] hard = < "Apple", "IBM", "Samsung">; // объединение последовательностей var result = soft.Union(hard); foreach (string s in result) Console.WriteLine(s);
Результатом операции будет следующий набор:
Microsoft Google Apple IBM Samsung
Если же нам нужно простое объединение двух наборов, то мы можем использовать метод Concat :
var result = soft.Concat(hard);
В этом случае те элементы, которые встречаются в обоих наборах, дублируются в резутирующей последовательности.
Последовательное применение методов Concat и Distinct будет подобно действию метода Union.
Работа со сложными объектами
Для сравнения объектов в последовательностях применяются реализации методов GetHeshCode() и Equals(). Поэтому если мы хотим работать с последовательностями, которые содержат объекты своих классов и структур, то нам необходимо определить для них подобные методы:
Person[] students = < new Person("Tom"), new Person("Bob"), new Person("Sam") >; Person[] employees = < new Person("Tom"), new Person("Bob"), new Person("Mike") >; // объединение последовательностей var people = students.Union(employees); foreach (Person person in people) Console.WriteLine(person.Name); class Person < public string Name < get;>public Person(string name) => Name = name; public override bool Equals(object? obj) < if (obj is Person person) return Name == person.Name; return false; >public override int GetHashCode() => Name.GetHashCode(); >
Здесь объекты Person сравниваются исходя из значения их свойства Name — если имена равны, то и объекты Person равны. Консольный вывод:
Python: коллекции, часть 3/4: объединение коллекций, добавление и удаление элементов
Для кого: для изучающих Python и уже имеющих начальное представление о коллекциях и работе с ними, желающих систематизировать и углубить свои знания, сложить их в целостную картину.
Оглавление:
- Объединение строк, кортежей, списков, словарей без изменения исходных.
- Объединение множеств без изменения исходных.
- Объединение списка, словаря и изменяемого множества с изменением исходной коллекции.
- Добавление и удаление элементов изменяемых коллекций.
- Особенности работы с изменяемой и не изменяемой коллекцией.
1. Объединение строк, кортежей, списков, словарей без изменения исходных
Рассмотрим способы объединения строк, кортежей, списков, словарей без изменения исходных коллекций — когда из нескольких коллекций создаётся новая коллекция того же тип без изменения изначальных.
-
Объединение строк (string) и кортежей (tuple) возможна с использованием оператора сложения «+»
str1 = 'abc' str2 = 'de' str3 = str1 + str2 print(str3) # abcde tuple1 = (1, 2, 3) tuple2 = (4, 5) tuple3 = tuple1 + tuple2 print(tuple3) # (1, 2, 3, 4, 5)
-
Добавляем все элементы второго списка к элементам первого, (аналог метод .extend() но без изменения исходного списка):
a = [1, 2, 3] b = [4, 5] c = a + b print(a, b, c) # [1, 2, 3] [4, 5] [1, 2, 3, 4, 5]
a = [1, 2, 3] b = [4, 5] c = a + [b] print(a, b, c) # [1, 2, 3] [4, 5] [1, 2, 3, [4, 5]]
a, b = [1, 2, 3], [4, 5] c = [*a, *b] # работает на версии питона 3.5 и выше print(c) # [1, 2, 3, 4, 5]
Сложить два словаря чтобы получить третий оператором + Питон не позволяет «TypeError: unsupported operand type(s) for +: ‘dict’ and ‘dict’».
Это можно сделать по-другому комбинируя методы .copy() и .update():
dict1 = dict2 = dict3 = dict1.copy() dict3.update(dict2) print(dict3) #
В Питоне 3.5 появился новый более изящный способ:
dict1 = dict2 = dict3 = <**dict1, **dict2>print(dict3) #
2. Объединение множеств без изменения исходных
Для обоих типов множеств (set, frozenset) возможны различные варианты комбинации множеств (исходные множества при этом не меняются — возвращается новое множество).

# Зададим исходно два множества (скопировать перед каждым примером ниже) a = b = < 'b', 'c'># отступ перед b для наглядности
c = a.union(b) # c = b.union(a) даст такой же результат # c = a + b # Обычное объединение оператором + не работает # TypeError: unsupported operand type(s) for +: 'set' and 'set' c = a | b # Альтернативная форма записи объединения print(c) #
c = a.intersection(b) # c = b.intersection(a) даст такой же результат c = a & b # Альтернативная форма записи пересечения print(c) #
Пересечение более 2-х множеств сразу:
a = b = < 'b', 'c'>c = < 'b', 'd'>d = a.intersection(b, c) # Первый вариант записи d = set.intersection(a, b, c) # Второй вариант записи (более наглядный) print(d) #
c = a.difference(b) # c = a - b другой способ записи дающий тот же результат print(c) # c = b.difference(a) # c = b - a другой способ записи дающий тот же результат print(c) #
c = b.symmetric_difference(a) # c = a.symmetric_difference(b) # даст такой же результат c = b ^ a # Альтернативная форма записи симметричной разницы print(c) #
3. Объединение списка, словаря и изменяемого множества с изменением исходной коллекции
-
Добавляем все элементы второго списка к элементам первого с измением первого списка методом .extend():
a.extend(b) # a += b эквивалентно a.extend(b) print(a, b) # [1, 2, 3, 4, 5] [4, 5]
a.append(b) # a += [b] эквивалентно a.append(b) print(a, b) # [1, 2, 3, [4, 5]] [4, 5]
Обратите внимание: для совпадающих ключей словаря при этом обновляются значения:
dict1 = dict2 = dict1.update(dict2) print(dict1) #
a = b = < 'b', 'c'>a.difference_update(b) print(a, b) # a = b = < 'b', 'c'>b.difference_update(a) print(a, b) #
a = b = < 'b', 'c'>a.intersection_update(b) print(a, b) # a = b = < 'b', 'c'>b.intersection_update(a) print(a, b) #
a = b = < 'b', 'c'>a.symmetric_difference_update(b) print(a, b) # a = b = < 'b', 'c'>b.symmetric_difference_update(a) print(a, b) #
4 Добавление и удаление элементов изменяемых коллекций
Добавление и удаление элементов в коллекцию возможно только для изменяемых коллекций: списка (list), множества (только set, не frozenset), словаря (dict). Причём для списка, который является индексированной коллекцией, также важно на какую позицию мы добавляем элемент.

Примеры использования метода .insert(index, element)
my_list = [1, 2, 3] my_list.insert(0, 0) # index = 0 - вставляем в начало print(my_list) # [0, 1, 2, 3] my_list.insert(10, 4) # Индекс выходит за границы списка - просто добавим в конец print(my_list) # [0, 1, 2, 3, 4] my_list.insert(-10, -1) # Индекс выходит за границы в минус - добавим в начало print(my_list) # [-1, 0, 1, 2, 3, 4] my_list = [1, 2, 3] my_list.insert(1, 1.5) # Вставим между 1 и 2 (индексация с нуля!) # То есть вставляется на позицию с указанным индексом, а то значение что на ней было # и те что правее - сдвигаются на 1 индекс вправо print(my_list) # [1, 1.5, 2, 3]
Примеры использования оператора del
# Работает со списком my_list = [1, 2, 3, 4, 5, 6, 7] del my_list[1] # Удаление элемента по индексу print(my_list) # [1, 3, 4, 5, 6, 7] del my_list[-3:-1] # Удаление элементов выбранных срезом print(my_list) # [1, 3, 4, 7] # del my_list[10] # IndexError: list assignment index out of range # Работает со словарем my_dict = del my_dict['b'] print(my_dict) # # del my_dict['z'] # KeyError при попытке удалить не сушествующий
5 Особенности работы с изменяемой и не изменяемой коллекцией
-
Строка неизменяемая коллекция — если мы ее меняем — мы создаем новый объект!
str1 = 'abc' print(str1, id(str1)) # abc 140234080454000 str1 += 'de' print(str1, id(str1)) # abcde 140234079974992 - Это НОВЫЙ объект, с другим id!
Пример кода с двумя исходно идентичными строками.
str1 = 'abc' str2 = str1 print(str1 is str2) # True - это две ссылки на один и тот же объект! str1 += 'de' # Теперь переменная str1 ссылается на другой объект! print(str1 is str2) # False - теперь это два разных объекта! print(str1, str2) # abcde abc - разные значения
list1 = [1, 2, 3] list2 = list1 print(list1 is list2) # True - это две ссылки на один и тот же объект! # А дальше убеждаемся, насколько это важно: list1 += [4] print(list1, list2) # [1, 2, 3, 4] [1, 2, 3, 4] # изменилось значение ОБЕИХ переменных, так как обе переменные ссылаются на один объект!
А если нужна независимая копия, с которой можно работать отдельно?
list1 = [1, 2, 3] list2 = list(list1) # Первый способ копирования list3 = list1[:] # Второй способ копирования list4 = list1.copy() # Третий способ копировани - только в Python 3.3+ print(id(list1), id(list2), id(list3), id(list4)) # все 4 id разные, что значит что мы создали 4 разных объекта list1 += [4] # меняем исходный список print(list1, list2, list3, list4) # [1, 2, 3, 4] [1, 2, 3] [1, 2, 3] [1, 2, 3] # как мы и хотели - изменив исходный объект, его копии остались не тронутыми
Приглашаю к обсуждению:
- Если я где-то допустил неточность или не учёл что-то важное — пишите в комментариях, важные комментарии будут позже добавлены в статью с указанием вашего авторства.
- Если какие-то моменты не понятны и требуется уточнение — пишите ваши вопросы в комментариях — или я или другие читатели дадут ответ, а дельные вопросы с ответами будут позже добавлены в статью.
Объединить коллекции
что именно вы хотите получить? Также что из себя представляют ‘bnb три коллекции?
14 июл 2015 в 14:44
Хочу Foreach вывести все в Gridview. Коллекции это выборка по JSON файлу
14 июл 2015 в 14:47
Gridview и foreach отношения к вопросу не имеют. Каким должен быть результат? И что это за выборки? У вас слишком расплывчатый вопрос
14 июл 2015 в 14:48
Как мне соединить все три коллекции как в случаи с Linq. Хочу обращаться к полям по именам.