Как получить равное количество элементов после деления диапазона, оставляя остаток

Давайте начнем с начала и исследователя немного глубже:

Итак, у вас есть два списка:

list_1=['01','98']
list_2=[['01','98']]

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

Итак, сначала попробуем общий метод копирования:

copy=list_1

Теперь, если вы думаете, что копия скопировала список_1, вы можете Неправильно, давайте проверим:

The id() function shows us that both variables point to the same list object, i.e. they share this object.
print(id(copy))
print(id(list_1))

output:

4329485320
4329485320

Удивлен? Итак, давайте рассмотрим это:

Итак, поскольку мы знаем, что python ничего не хранит в переменной, переменные просто ссылаются на объект и объект хранят значение. Здесь object list, но мы создали две ссылки на тот же объект двумя разными именами переменных. Таким образом, обе переменные указывают на один и тот же объект:

, поэтому, когда вы делаете copy=list_1, что на самом деле его делает:

Здесь в изображении list_1 и copy находятся два имени переменной, но объект одинаковый для обеих переменных, который является list

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

copy[0]="modify"

print(copy)
print(list_1)

output:

['modify', '98']
['modify', '98']

Так что он изменил Исходный список:

Что такое решение?

Решение:

Теперь перейдем ко второму питоническому методу копирования списка :

copy_1=list_1[:]

Теперь этот метод исправить то, с чем мы столкнулись в первом выпуске, давайте проверим его:

print(id(copy_1))
print(id(list_1))

4338792136
4338791432

Итак, мы можем видеть, что оба наших списка имеют разные id и это означает, что обе переменные указывают на разные объекты, так что здесь происходит следующее:

N ow давайте попробуем изменить список и посмотрим, остаемся ли мы перед предыдущей проблемой:

copy_1[0]="modify"

print(list_1)
print(copy_1)

Выход:

['01', '98']
['modify', '98']

Итак, вы можете видеть, что он не изменяет первоначальный список, он только изменил скопированный список, поэтому с нами все в порядке.

Итак, теперь я думаю, что мы закончили? подождите, мы должны скопировать второй вложенный список, так что давайте попробуем pythonic way:

copy_2=list_2[:]

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

print(id((list_2)),id(copy_2))

получаем результат:

4330403592 4330403528

Теперь мы можем предположить, что оба списка указывают на другой объект, поэтому теперь давайте попробуем его модифицировать и посмотрим, что он дает то, что мы хотим:

Поэтому, когда мы пытаемся:

copy_2[0][1]="modify"

print(list_2,copy_2)

, он дает нам вывод:

[['01', 'modify']] [['01', 'modify']]

Теперь, это немного запутывает, мы использовали питоновский путь, и все же мы сталкиваемся с той же проблемой .

давайте поймем это:

Итак, когда мы делаем:

copy_2=list_2[:]

, мы фактически копируем только внешний список, а не вложенный список, поэтому вложенный list - тот же объект для обоих списков, давайте проверим:

print(id(copy_2[0]))
print(id(list_2[0]))

output:

4329485832
4329485832

Так что, фактически, когда мы делаем copy_2=list_2[:], это происходит:

Создает копию списка, но только внешнюю копию списка, а не вложенную копию списка, вложенный список одинаковый для обеих переменных, поэтому, если вы попытаетесь изменить modi fy вложенного списка, то он также изменит исходный список, потому что вложенный объект списка одинаковый для обоих вложенных списков.

Итак, каково решение?

Решение - deep copy

from copy import deepcopy
deep=deepcopy(list_2)

Итак, теперь давайте проверим:

print(id((list_2)),id(deep))

вывод:

4322146056 4322148040

оба идентификатора разные, теперь давайте проверим идентификатор вложенного списка:

print(id(deep[0]))
print(id(list_2[0]))

output:

4322145992
4322145800

Как вы можете видеть, оба идентификатора различны, поэтому мы можем предположить, что оба вложенных списка теперь указывают на другой объект.

So когда вы делаете deep=deepcopy(list_2), что на самом деле происходит:

Таким образом, оба вложенных списка указывают на другой объект, и теперь они имеют отдельную копию вложенного списка.

Теперь попробуем изменить вложенный список и посмотрим, разрешила ли он предыдущую проблему или нет:

, так что если мы это сделаем:

deep[0][1]="modify"
print(list_2,deep)

вывод:

[['01', '98']] [['01', 'modify']]

Итак, вы можете видеть, что он не изменил исходный вложенный список, он только изменил скопированный список.

Если вам понравился мой подробный ответ, сообщите мне об этом, если вы сомневаетесь в этом ответе, прокомментируйте:)

1
задан Flora Biletsiou 24 March 2019 в 02:23
поделиться

2 ответа

Если ваша задача - проверить, является ли число простым, удобно, чтобы большие числа были в меньших группах (так как сложнее проверить, что они являются простыми числами).

Вы можете использовать политику, начатую MAX. Затем создайте следующий интервал: {MAX-1, MAX-2}, например (и т. Д.), Пока у вас не будет количества требуемых диапазонов.

0
ответ дан Dante Haversham 24 March 2019 в 02:23
поделиться

Как получить равное количество элементов после разделения диапазона, оставляя остаток

Различные подходы.

Ключевой вопрос заключается в том, включены ли 0 и 10 в целочисленный диапазон: это [0... 10] или [0... 10) или ...? Обратите внимание на ] или )? Предположим, что конечные точки списков включены, и [0... 10] представляет собой 11 различных целочисленных значений.

Примечание. Существуют такие крайности, как 11 чисел, разделенных на 12 групп.

Нижеследующее формирует поддиапазон из первой 1/n части диапазона, затем 1/(n-1) части оставшегося диапазона и т. Д.

void range(int n, int inclusive_min, int inclusive_max) {
  printf("Range [%d %d] / %d\n", inclusive_min, inclusive_max, n);
  for(int i = n; i > 0 && inclusive_min <= inclusive_max; i--) {
    int range = 1 + inclusive_max - inclusive_min;
    int sub_range = range/i;
    if (sub_range == 0) sub_range = 1;
    printf("Sub range [%d %d]\n", inclusive_min, inclusive_min + sub_range - 1);
    inclusive_min += sub_range;
  }
}

int main(void) {
  range(3, 0, 10);
  range(2, 0, 10);
  range(5, 0, 10);
  range(3, 0, 1);
  return 0;
}

Выходные данные

Range [0 10] / 3
Sub range [0 2]
Sub range [3 6]
Sub range [7 10]
Range [0 10] / 2
Sub range [0 4]
Sub range [5 10]
Range [0 10] / 5
Sub range [0 1]
Sub range [2 3]
Sub range [4 5]
Sub range [6 7]
Sub range [8 10]
Range [0 1] / 3
Sub range [0 0]
Sub range [1 1]
<час>

Более элегантное решение, похожее на алгоритм линии Брезенхема

void range(int n, int inclusive_min, int inclusive_max) {
  printf("Range [%d %d] / %d\n", inclusive_min, inclusive_max, n);
  int range = 1 + inclusive_max - inclusive_min;
  int sub_range = range / n;
  int sub_range_res = range % n;
  int p = 0;
  for (int i = 0; i < n; i++) {
    int next = inclusive_min + sub_range;
    p += sub_range_res;
    if (2 * p >= n) {  // like p >= n/2 without integer truncation.
      p -= n;
      next++;
    }
    if (next > inclusive_min) {
      printf("Sub range %d:[%d %d]\n", i, inclusive_min, next - 1);
    }
    inclusive_min = next;
  }
}

Выходные данные

[113 ]
0
ответ дан chux 24 March 2019 в 02:23
поделиться
Другие вопросы по тегам:

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