Перейти к содержимому

Как объединить две коллекции c

  • автор:

Подскажите как быстро соединить две отсортированные коллекции

привет
есть штук 10 коллекций объектов отсортированных по полю datatime
суммарное количество элементов — 30 000 000
подскажите как быстрее всего собрать из этих коллекций в одну — отсортированную по этому же полю

Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Как быстро соединить много csv Файлов?
Как быстро соединить много csv Файлов? Данных в таблицах много, но количество столбцов одинаково.

Как наиболее быстро соединить все слова в одну строку через запятую?
Как по бистрому соеденить все слова в одну строку через кому? (можно через контатенацию) Слова.

Как соединить две программы?
Помогите плиз, подскажите как соединить 2 программы

как соединить две линии в одну
мне нужно написать программу, которая соединяет две выбранные линии в одну: начальную точку первой.

Эксперт .NET

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. Объединение строк, кортежей, списков, словарей без изменения исходных.
  2. Объединение множеств без изменения исходных.
  3. Объединение списка, словаря и изменяемого множества с изменением исходной коллекции.
  4. Добавление и удаление элементов изменяемых коллекций.
  5. Особенности работы с изменяемой и не изменяемой коллекцией.

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) возможны различные варианты комбинации множеств (исходные множества при этом не меняются — возвращается новое множество).

image

# Зададим исходно два множества (скопировать перед каждым примером ниже) 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). Причём для списка, который является индексированной коллекцией, также важно на какую позицию мы добавляем элемент.

image

Примеры использования метода .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. Хочу обращаться к полям по именам.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *