Очень простой подход, не зависящий от версии python, отсутствовал в уже заданных ответах, которые вы можете использовать большую часть времени (по крайней мере, я):
new_list = my_list * 1 #Solution 1 when you are not using nested lists
Однако, если my_list содержит другие контейнеры ( например, вложенных списков), вы должны использовать функцию глубокой печати, как другие, предложенные в ответах выше, из библиотеки копий. Например:
import copy
new_list = copy.deepcopy(my_list) #Solution 2 when you are using nested lists
.Bonus: Если вы не хотите копировать элементы, используйте (ака мелкой копии):
new_list = my_list[:]
Давайте понимать разницу между решением # 1 и Solution # 2
>>> a = range(5)
>>> b = a*1
>>> a,b
([0, 1, 2, 3, 4], [0, 1, 2, 3, 4])
>>> a[2] = 55
>>> a,b
([0, 1, 55, 3, 4], [0, 1, 2, 3, 4])
Как вы можете видеть, решение № 1 отлично работало, когда мы не использовали вложенные списки. Давайте проверим, что произойдет, когда мы применим решение №1 к вложенным спискам.
>>> from copy import deepcopy
>>> a = [range(i,i+4) for i in range(3)]
>>> a
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
>>> b = a*1
>>> c = deepcopy(a)
>>> for i in (a, b, c): print i
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
>>> a[2].append('99')
>>> for i in (a, b, c): print i
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5, 99]]
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5, 99]] #Solution#1 didn't work in nested list
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]] #Solution #2 - DeepCopy worked in nested list
Вы можете разбить цикл на диапазоны индексов ковша, а затем создать итератор с внутренним байтом для обработки элементов. unordered_map
имеет .bucket_count()
и специфичные для ведра значения итератора begin(bucket_number)
, end(bucket_number)
, которые позволяют это. Предполагая, что вы не изменили значение по умолчанию max_load_factor()
с 1.0 и имеете разумную хэш-функцию, вы будете average 1 элемент на каждый ковш и не должны тратить слишком много времени на пустые ведра.
Канонический подход с контейнерами, которые не поддерживают случайные итераторы, заключается в использовании явных задач OpenMP:
std::unordered_map<size_t, double> hastTable;
#pragma omp parallel
{
#pragma omp single
{
for(auto it = hastTable.begin(); it != hastTable.end(); it++) {
#pragma omp task
{
//do something
}
}
}
}
Это создает отдельную задачу для каждой итерации, которая приносит некоторые накладные расходы и поэтому имеет смысл только тогда, когда //do something
на самом деле означает //do quite a bit of work
.
unordered_map
не являются случайным доступом ... это заслуживающее доверия объяснение, так как процедуры параллелизации, вероятно, предполагают, что накладные расходы итераций являются значительными по сравнению с обработкой данных для каждого элемента данных, поэтому некоторые неизвестные количество смещения будет хотеть создавать последовательно меньшие партии, так как итерация прогрессирует так, что они заканчиваются примерно в одно и то же время. – Tony Delroy 25 September 2014 в 16:35