Список 1 и 2: 1.2. СПИСОК N 2 ПРОИЗВОДСТВ, РАБОТ, ПРОФЕССИЙ, ДОЛЖНОСТЕЙ И ПОКАЗАТЕЛЕЙ С ВРЕДНЫМИ И ТЯЖЕЛЫМИ УСЛОВИЯМИ ТРУДА, ЗАНЯТОСТЬ В КОТОРЫХ ДАЕТ ПРАВО НА ПЕНСИЮ ПО ВОЗРАСТУ (ПО СТАРОСТИ) НА ЛЬГОТНЫХ УСЛОВИЯХ

Разное

«О невозможности суммирования к периоду работы по Списку № 1 периода работы по Списку № 2»

Мужчина имеет 24 года страхового стажа и 7 лет специального стажа на работах, дающих право на досрочную страховую пенсию по старости по Списку № 1, что недостаточно для назначения ему указанной пенсии по достижении 50 лет (мужчине требуется не менее 10 лет соответствующего стажа при страховом стаже не менее 20 лет). Кроме указанного стажа мужчина имеет 6 лет стажа на работах, предусмотренных в Списке № 2. Можно ли суммировать эти два периода его работы и назначить мужчине досрочную пенсию по Списку № 1, т.е. на 10 лет раньше общеустановленного возраста?

Действующее законодательство при определении права на досрочное назначение страховой пенсии по старости предусматривает суммирование стажа на соответствующих видах работ. Порядок суммирования периодов работ, дающих право на досрочное назначение трудовой пенсии по старости, установлен соответствующими Правилами (пункты 2 и 3), утвержденными постановлением Правительства Российской Федерации от 11 июля 2002 года № 516. В основу суммирования положен принцип объединения периодов работы с равнозначными требованиями (условиями) по возрасту, страховому стажу и стажу на соответствующих видах работ, а также принцип присоединения периодов работы с меньшими требованиями к периодам работы с большими требованиями по возрасту, страховому стажу и стажу на соответствующих видах работ.

Указанными Правилами не предусмотрено присоединение периодов работ, дающих право на досрочную страховую пенсию по старости в соответствии со Списком № 2, к периодам работ, предусмотренных в Списке № 1. При таких обстоятельствах не может быть применим порядок суммирования указанных периодов работ с целью назначения мужчине досрочной страховой пенсии по старости в соответствии со Списком № 1 по достижении им возраста 50 лет. В данном случае допускается присоединение к периоду работы, дающей право на досрочное пенсионное обеспечение по Списку № 2 (6 лет), периода работы, дающей право на досрочное пенсионное обеспечение по Списку № 1 (7 лет), в целях назначения досрочной пенсии по Списку № 2 в возрасте 55 лет мужчине.

Согласно пункту 1 части 1 статьи 30 Закона от 28.12.2013 г. мужчинам страховая пенсия по старости назначается по достижении возраста 50 лет, если они проработали не менее 10 лет на подземных работах, на работах с вредными условиями труда и в горячих цехах (Список № 1) и имеют страховой стаж не менее 20 лет. В случае если мужчина не выработал необходимого стажа на указанных работах, но имеет его не менее половины требуемого срока и имеет требуемую продолжительность страхового стажа, страховая пенсия по старости ему может назначаться с уменьшением возраста, установленного статьей 8 Закона от 28.12.2013 г (60 лет), на один год за каждый полный год такой работы.

С учетом изложенного страховая пенсия по старости мужчине при наличии указанного страхового стажа и стажа на соответствующих видах работ может быть назначена в соответствии со Списком № 1 по достижении возраста 53 лет.

По информации управления Пенсионного Фонда РФ в Каменске-Уральском

ГПИБ | Список гражданским чинам первых четырех классов.

Ч. 1-2. ГПИБ | Список гражданским чинам первых четырех классов. Ч. 1-2. — СПб. ; Пг., 1873-1916.

10770 / 12876

Электронная библиотека ГПИБ Книжные издания Список гражданским чинам первых четырех классов. Ч. 1-2. — СПб. ; П…

Описание

Библиографическое описание

Список гражданским чинам первых четырех классов. Исправлено по… [1873-1916]. Ч. 1-2. — СПб. ; Пг., 1873-1916. — Изд. 2 раза в год; Списки чинам расположены по классам, затем по дате производства в последний чин; Сведения о движении по службе с указанием всех чинов и даты производства, наградах по годам (орденов, благодарностей, подарков и пр.), размерах получаемого содержания (все виды довольствия), наличии недвижимого имущества.

[Ч.1]. Список гражданским чинам первых трех классов. Исправлено по… [1873-1916]. — СПб. ; Пг., 1873-1916.

[Ч. 2]. Список гражданским чинам четвертого класса. Исправлено по… [1873-1916].

— СПб. ; Пг., 1873-1916.

Тип издания книжное издание (24463)
Заглавие Список гражданским чинам первых четырех классов. Исправлено по… [1873-1916]. Ч. 1-2 (1)
Место издания СПб. (3132)
Издательство Тип. Правительствующего Сената (13)
Год издания 1873-1916 (1)
Примечание

Изд. 2 раза в год; Списки чинам расположены по классам, затем по дате производства в последний чин; Сведения о движении по службе с указанием всех чинов и даты производства, наградах по годам (орденов, благодарностей, подарков и пр.), размерах получаемого содержания (все виды довольствия), наличии недвижимого имущества.

[Ч.1]. Список гражданским чинам первых трех классов. Исправлено по… [1873-1916]. — СПб. ; Пг., 1873-1916.

[Ч. 2]. Список гражданским чинам четвертого класса. Исправлено по… [1873-1916]. — СПб. ; Пг., 1873-1916.

Коллекции Адрес-календари, памятные и справочные книги (245)
Комментарии

Список гражданским чинам первых трех классов. Исправлен по 15-е января 1870 года. — СПб., [1870] — добавлен именно к этому электронному изданию по аналогии оформления с Ч.1 выпуска 1873 года

  • Список гражданским чинам первых трех классов. Исправлен по 15-е января 1870 года. — СПб., [1870].

  • …по 10-е января 1873 года. Ч. 1 : Чины первых трех классов. — СПб., 1873.

  • …по 10-е мая 1873 года. Ч. 1 : Чины первых трех классов. — СПб., 1873.

  • …по 10-е мая 1874 года. Ч. 1 : Чины первых трех классов. — СПб., 1874.

  • Список гражданским чинам первых трех классов. Исправлен по 26-е февраля 1876 года. — [СПб., 1876]

  • Список гражданским чинам первых трех классов. Исправлен по 10-е мая 1877 года. — [СПб., 1877].

  • [Список гражданским чинам первых трех классов. Исправлен по 1-е октября 1877 года]. — СПб., [1877].

  • Список гражданским чинам первых трех классов. Исправлен по 1-е июня 1878 года. — СПб., 1878.

slice — Как работает нарезка в Python

В приведенных выше ответах не обсуждается назначение слайсов. Чтобы понять назначение слайсов, полезно добавить еще одно понятие в искусство ASCII:

 +---+---+---+---+---+---+
                | П | у | т | ч | о | н |
                +---+---+---+---+---+---+
Позиция среза: 0 1 2 3 4 5 6
Позиция индекса: 0 1 2 3 4 5
>>> p = ['P','y','t','h','o','n']
# Почему два набора чисел:
# индексация дает элементы, а не списки
>>> р[0]
 'П'
>>> стр[5]
 'н'
# Нарезка дает списки
>>> р[0:1]
 ['П']
>>> р[0:2]
 ['П','у']
 

Одна из эвристик, для среза от нуля до n, подумайте: «ноль — это начало, начните с начала и возьмите n элементов в списке».

 >>> p[5] # последний из шести элементов, пронумерованных с нуля
 'н'
>
>> p[0:5] # НЕ включает последний элемент! ['П','у','т','ч','о'] >>> p[0:6] # не p[0:5]!!! ['П','у','т','ч','о','н']

Другая эвристика: «для любого среза замените начало на ноль, примените предыдущую эвристику, чтобы получить конец списка, затем подсчитайте первое число, чтобы отрезать элементы от начала»

 >>> p[0:4] # Начать сначала и отсчитать 4 элемента
 ['П','у','т','ч']
>>> p[1:4] # Убираем один элемент с лицевой стороны
 ['у','т','ч']
>>> p[2:4] # Убираем два предмета с лицевой стороны
 ['т', 'ч']
# и т. д.
 

Первое правило назначения среза состоит в том, что, поскольку срез возвращает список, назначение среза требует списка (или другого итерируемого):

 >>> p[2:3]
 ['т']
>>> р[2:3] = ['Т']
>>> р
 ['П','у','Т','ч','о','н']
>>> р[2:3] = 'т'
Traceback (последний последний вызов):
  Файл "", строка 1, в 
TypeError: можно назначить только итерируемый
 

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

 >>> p[2:4 ]
 ['Т','ч']
>>> p[2:4] = ['t','r']
>>> р
 ['П','у','т','р','о','н']
 

Третье правило назначения слайсов: назначенный список (итерируемый) не должен иметь одинаковую длину; индексированный фрагмент просто вырезается и целиком заменяется тем, что присваивается:

 >>> p = ['P','y','t','h','o','n'] # Начать сначала
>>> p[2:4] = ['s','p','a','m']
>>> р
 ['P','y','s','p','a','m','o','n']
 

Самая сложная часть, к которой нужно привыкнуть, — это присваивание пустым слайсам. Используя эвристику 1 и 2, легко разобраться с , индексируя пустой фрагмент:

 >>> p = ['P','y','t','h','o','n' ]
>>> р[0:4]
 ['П','у','т','ч']
>>> р[1:4]
 ['у','т','ч']
>>> р[2:4]
 ['т', 'ч']
>>> р[3:4]
 ['час']
>>> р[4:4]
 []
 

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

 >>> p = ['P','y','t','h','o',' п']
>>> p[2:4] = ['x','y'] # Назначенный список имеет ту же длину, что и срез
>>> р
 ['P','y','x','y','o','n'] # Результат одинаковой длины
>>> p = ['P','y','t','h','o','n']
>>> p[3:4] = ['x','y'] # Назначенный список длиннее среза
>>> р
 ['P','y','t','x','y','o','n'] # Результат длиннее
>>> p = ['P','y','t','h','o','n']
>>> р[4:4] = ['х','у']
>>> р
 ['P','y','t','h','x','y','o','n'] # Результат еще длиннее
 

Обратите внимание, что, поскольку мы не меняем второй номер слайса (4), вставляемые элементы всегда располагаются прямо напротив буквы «о», даже когда мы назначаем пустой слайс. Таким образом, позиция для назначения пустого слайса является логическим продолжением позиций для назначений непустого слайса.

Немного отступив назад, что произойдет, если вы продолжите нашу процессию подсчета начала среза?

 >>> p = ['P','y','t','h','o','n']
>>> р[0:4]
 ['П','у','т','ч']
>>> р[1:4]
 ['у','т','ч']
>>> р[2:4]
 ['т', 'ч']
>>> р[3:4]
 ['час']
>>> р[4:4]
 []
>>> р[5:4]
 []
>>> р[6:4]
 []
 

С нарезкой, как только вы закончите, все готово; он не начинает резать назад. В Python вы не получите отрицательных шагов, если вы явно не запросите их, используя отрицательное число.

 >>> р[5:3:-1]
 ['нет']
 

Есть несколько странных следствий правила «как только вы закончите, вы закончите»:

 >>> p[4:4]
 []
>>> р[5:4]
 []
>>> р[6:4]
 []
>>> стр[6]
Traceback (последний последний вызов):
  Файл "", строка 1, в 
IndexError: индекс списка вне допустимого диапазона
 

На самом деле, по сравнению с индексированием, нарезка Python на удивление устойчива к ошибкам:

 >>> p[100:200]
 []
>>> p[int(2e99):int(1e99)]
 []
 

Иногда это может пригодиться, но также может привести к несколько странному поведению:

 >>> p
 ['П', 'у', 'т', 'ч', 'о', 'н']
>>> p[int(2e99):int(1e99)] = ['p','o','w','e','r']
>>> р
 ['P', 'y', 't', 'h', 'o', 'n', 'p', 'o', 'w', 'e', ​​'r']
 

В зависимости от вашего приложения это может.

.. а может и нет… быть тем, на что вы надеялись!


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

 >>> г=[1,2,3,4]
>>> г[1:1]
[]
>>> г[1:1]=[9,8]
>>> г
[1, 9, 8, 2, 3, 4]
>>> г[1:1]=['бла']
>>> г
[1, 'бла', 9, 8, 2, 3, 4]
 

Это также может прояснить разницу между нарезкой и индексацией.

python — список изменений списков, неожиданно отраженных в подсписках

Задавать вопрос

спросил

14 лет, 6 месяцев назад

Изменено 2 месяца назад

Просмотрено 75 тысяч раз

Я создал список списков:

 >>> xs = [[1] * 4] * 3
>>> печатать(хз)
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
 

Затем я изменил одно из самых внутренних значений:

 >>> хс[0][0] = 5
>>> печатать(хз)
[[5, 1, 1, 1], [5, 1, 1, 1], [5, 1, 1, 1]]
 

Почему каждый первый элемент каждого подсписка изменился на 5 ?


См. также:

  • Как клонировать список, чтобы он не изменился неожиданно после назначения? для решения проблемы

  • Список словарей сохраняет только последнее добавленное значение на каждой итерации для аналогичной задачи со списком словарей

  • Как инициализировать словарь пустых списков в Python? для аналогичной задачи с диктом списков

  • python
  • список
  • вложенные списки
  • изменяемый
4

Когда вы пишете [x]*3 , вы получаете, по сути, список [x, x, x] . То есть список с 3-мя ссылками на те же x . Когда вы затем измените этот сингл x видно через все три ссылки на него:

 x = [1] * 4
хз = [х] * 3
печать (е "идентификатор (х): {идентификатор (х)}")
# идентификатор (х): 140560897920048
Распечатать(
    f"id(xs[0]): {id(xs[0])}\n"
    f"id(xs[1]): {id(xs[1])}\n"
    f"id(xs[2]): {id(xs[2])}"
)
# идентификатор (хз [0]): 140560897920048
# идентификатор (хз [1]): 140560897920048
# идентификатор (хз [2]): 140560897920048
х[0] = 42
распечатать (ф "х: {х}")
# х: [42, 1, 1, 1]
печать (ф "xs: {xs}")
# xs: [[42, 1, 1, 1], [42, 1, 1, 1], [42, 1, 1, 1]]
 

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

 [[1]*4 для _ в диапазоне(3)]
 

, который будет пересчитывать [1] * 4 каждый раз вместо того, чтобы вычислять его один раз и делать 3 ссылки на 1 список.


Вы можете задаться вопросом, почему * не может создавать независимые объекты так, как это делает понимание списка. Это потому, что оператор умножения * работает с объектами, не видя выражений. Когда вы используете * для умножения [[1] * 4] на 3, * видит только одноэлементный список [[1] * 4] вычисляется, а не текст выражения [[1] * 4 . * понятия не имеет, как сделать копии этого элемента, понятия не имеет, как переоценить [[1] * 4] , и понятия не имеет, что вам нужны копии, и вообще, возможно, даже не существует способа скопировать элемент.

Единственный вариант, который есть у * , — это создавать новые ссылки на существующий подсписок вместо того, чтобы пытаться создавать новые подсписки. Все остальное было бы непоследовательным или потребовало серьезной переработки фундаментальных решений по проектированию языка.

Напротив, генератор списка пересчитывает выражение элемента на каждой итерации. [[1] * 4 для n в диапазоне (3)] пересчитывает [1] * 4 каждый раз по той же причине [x**2 для x в диапазоне (3)] пересчитывает x** 2 каждый раз. Каждое вычисление [1] * 4 генерирует новый список, поэтому понимание списка делает то, что вы хотели.

Между прочим, [1] * 4 также не копирует элементы [1] , но это не имеет значения, так как целые числа неизменяемы. Вы не можете сделать что-то вроде 1.value = 2 и превратить 1 в 2.

6

 размер = 3
matrix_surprise = [[0] * размер] * размер
матрица = [[0]*размер для _ в диапазоне (размер)]
 

Живая визуализация с использованием Python Tutor:

5

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

Вы пишете

 lst = [[1] * 4] * 3
 

Это эквивалентно:

 lst1 = [1]*4
лст = [лст1]*3
 

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

 lst[0][0] = 5
лст1[0] = 5
 

Так как lst[0] есть не что иное, как lst1 .

Чтобы получить желаемое поведение, вы можете использовать понимание списка:

 lst = [[1]*4 для n в диапазоне (3)]
 

В этом случае выражение пересчитывается каждые n , ведущие к другому списку.

3

 [[1] * 4] * 3
 

или даже:

 [[1, 1, 1, 1]] * 3
 

Создает список, который ссылается на внутренний [1,1,1,1] 3 раза — не три копии внутреннего списка, поэтому каждый раз, когда вы изменяете список (в любой позиции), вы увидите изменение три раза.

То же, что и в этом примере:

 >>> inner = [1,1,1,1]
>>> внешний = [внутренний]*3
>>> внешний
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
>>> внутренний[0] = 5
>>> внешний
[[5, 1, 1, 1], [5, 1, 1, 1], [5, 1, 1, 1]]
 

, где это, вероятно, немного менее удивительно.

1

my_list = [[1]*4] * 3 создает один объект списка [1,1,1,1] в памяти и копирует его ссылку 3 раза. Это эквивалентно obj = [1,1,1,1]; мой_список = [объект]*3 . Любая модификация obj будет отражена в трех местах, где бы obj ни упоминался в списке. Правильным утверждением будет:

 my_list = [[1]*4 для _ в диапазоне(3)]
 

или

 my_list = [[1 для __ в диапазоне (4)] для _ в диапазоне (3)]
 

Важно отметить здесь , что оператор * в основном используется для создания списка литералов . Хотя 1 является неизменным, obj = [1]*4 все равно создаст список 1 , повторенный 4 раза, чтобы сформировать [1,1,1,1] . Но если делается какая-либо ссылка на неизменяемый объект, этот объект перезаписывается новым.

Это означает, что если мы сделаем obj[1] = 42 , то obj станет [1,42,1,1] , а не [42,42,42,42] , как некоторые могут предполагать. Это также можно проверить:

 >>> my_list = [1]*4
>>> мой_список
[1, 1, 1, 1]
>>> идентификатор (мой_список [0])
4522139440
>>> id(my_list[1]) # То же, что и my_list[0]
4522139440
 

 >>> my_list[1] = 42 # Поскольку my_list[1] неизменяем, эта операция перезаписывает my_list[1] новым объектом, меняющим свой идентификатор.
>>> мой_список
[1, 42, 1, 1]
>>> идентификатор (мой_список [0])
4522139440
>>> id(my_list[1]) # идентификатор изменен
4522140752
>>> id(my_list[2]) # id такой же, как у my_list[0], но ссылается на значение `1`.
4522139440
 
1

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

 [[1]*4 для _ в диапазоне (3)]
 

Кроме того, вы можете использовать itertools. repeat() для создания объекта итератора повторяющихся элементов:

 >>> a = список (повторить (1,4))
[1, 1, 1, 1]
>>> а[0] = 5
>>> а
[5, 1, 1, 1]
 

П.С. Если вы используете NumPy и хотите создать массив только из единиц или нулей, вы можете использовать np.ones и np.zeros и/или для других чисел используйте np.repeat :

 >>> импортировать numpy как np
>>> np.ones(4)
массив([1., 1., 1., 1.])
>>> np.ones((4, 2))
массив([[1., 1.],
       [1., 1.],
       [1., 1.],
       [1., 1.]])
>>> np.zeros((4, 2))
массив([[0., 0.],
       [0., 0.],
       [0., 0.],
       [0., 0.]])
>>> np.repeat([7], 10)
массив([7, 7, 7, 7, 7, 7, 7, 7, 7, 7])
 

Контейнеры Python содержат ссылки на другие объекты. См. этот пример:

 >>> a = []
>>> б = [а]
>>> б
[[]]
>>> а. добавить(1)
>>> б
[[1]]
 

В этом b список, содержащий один элемент, который является ссылкой на список a . Список и является изменяемым.

Умножение списка на целое число эквивалентно многократному сложению списка с самим собой (см. общие операции с последовательностями). Итак, продолжая пример:

 >>> с = б + б
>>> с
[[1], [1]]
>>>
>>> а[0] = 2
>>> с
[[2], [2]]
 

Мы видим, что список c теперь содержит две ссылки на список a , что эквивалентно c = b * 2 .

Часто задаваемые вопросы по Python также содержат объяснение этого поведения: Как создать многомерный список?

Я добавляю свой ответ, чтобы объяснить то же самое схематически.

То, как вы создали 2D, создает неглубокий список

 обр = [[0]*столбцы]*строка
 

Вместо этого, если вы хотите обновить элементы списка, вы должны использовать

 строки, cols = (5, 5)
arr = [[0 для i в диапазоне (столбцы)] для j в диапазоне (строки)]
 

Объяснение :

Можно создать список, используя:

 arr = [0]*N
 

или

 обр = [0 для i в диапазоне (N)]
 

В первом случае все индексы массива указывают на один и тот же целочисленный объект

и когда вы присваиваете значение определенному индексу, создается новый целочисленный объект, например arr[4] = 5 создает

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

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

Кредиты: Спасибо Пранаву Девараконде за простое объяснение здесь

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

Чтобы решить вашу проблему, вы можете выполнить одно из следующих действий: 1. Используйте документацию массива numpy для numpy.empty 2. Добавляйте список по мере его поступления. 3. Вы также можете использовать словарь, если хотите

Давайте перепишем ваш код следующим образом:

 x = 1
у = [х]
г = у * 4
мой_список = [г] * 3
 

Затем, имея это, запустите следующий код, чтобы все стало понятнее. Что делает код, так это печатает id полученных объектов, которые

Возвращает «идентификатор» объекта

и поможет нам идентифицировать их и проанализировать, что происходит:

 print("my_list:")
для i, sub_list в enumerate(my_list):
    print("\t[{}]: {}". format(i, id(sub_list)))
    для j, элемент в перечислении (sub_list):
        print("\t\t[{}]: {}".format(j, id(elem)))
 

И вы получите следующий вывод:

 x: 1
г: [1]
г: [1, 1, 1, 1]
мой список:
    [0]: 4300763792
        [0]: 4298171528
        [1]: 4298171528
        [2]: 4298171528
        [3]: 4298171528
    [1]: 4300763792
        [0]: 4298171528
        [1]: 4298171528
        [2]: 4298171528
        [3]: 4298171528
    [2]: 4300763792
        [0]: 4298171528
        [1]: 4298171528
        [2]: 4298171528
        [3]: 4298171528
 

Итак, давайте пошагово. У вас есть x , что равно 1 , и список одного элемента y , содержащий x . Ваш первый шаг — y * 4 , который даст вам новый список z , который в основном равен [x, x, x, x] , т.е. он создает новый список, который будет иметь 4 элемента, которые являются ссылками. к исходному объекту x . Следующий шаг очень похож. Вы в основном делаете z * 3 , что равно [[x, x, x, x]] * 3 и возвращает [[x, x, x, x], [x, x, x, x], [х, х, х, х]] по той же причине, что и для первого шага.

0

Все объясняют, что происходит. Я предлагаю один из способов ее решения:

 my_list = [[1 для i в диапазоне (4)] для j в диапазоне (3)]
мой_список[0][0] = 5
распечатать (мой_список)
 

И тогда вы получите:

 [[5, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
 

@spelchekr из умножения списка Python: [[…]]*3 создает 3 списка, которые отражают друг друга при изменении, и у меня был тот же вопрос о «Почему только внешние *3 создать больше ссылок, а внутреннюю нет? Почему не все единицы?»

 li = [0] * 3
print([id(v) для v в li]) # [140724141863728, 140724141863728, 140724141863728]
ли [0] = 1
print([id(v) для v в li]) # [140724141863760, 140724141863728, 140724141863728]
печать (id (0)) # 140724141863728
печать (id (1)) # 140724141863760
print(li) # [1, 0, 0]
ma = [[0]*3] * 3 # в основном обсуждаем внутренний и внешний *3 здесь
print([id(li) for li in ma]) # [1987013355080, 1987013355080, 1987013355080]
ма[0][0] = 1
print([id(li) for li in ma]) # [1987013355080, 1987013355080, 1987013355080]
print(ma) # [[1, 0, 0], [1, 0, 0], [1, 0, 0]]
 

Вот мое объяснение после попытки кода выше:

  • Внутренний *3 также создает ссылки, но его ссылки неизменяемы, что-то вроде [&0, &0, &0] , затем при изменении li[ 0] , вы не можете изменить базовую ссылку const int 0 , поэтому вы можете просто изменить адрес ссылки на новый &1 ;
  • в то время как ma = [&li, &li, &li] и li является изменяемым, поэтому, когда вы вызываете ma[0][0] = 1 , ma[0][0] равно &li [0] , поэтому все экземпляры &li изменят свой 1-й адрес на &1 .

Пытаясь объяснить это более наглядно,

Операция 1:

 x = [[0, 0], [0, 0]]
print(type(x)) # <класс 'список'>
print(x) # [[0, 0], [0, 0]]
х [0] [0] = 1
print(x) # [[1, 0], [0, 0]]
 

Операция 2:

 г = [[0] * 2] * 2
print(type(y)) # <класс 'список'>
print(y) # [[0, 0], [0, 0]]
у [0] [0] = 1
print(y) # [[1, 0], [1, 0]]
 

Заметили, почему изменение первого элемента первого списка не приводит к изменению второго элемента каждого списка? Это потому, что [0] * 2 на самом деле представляет собой список из двух чисел, и ссылку на 0 нельзя изменить.

Если вы хотите создать клонированные копии, попробуйте операцию 3:

 импортировать копию
у = [0] * 2
напечатать(у) # [0, 0]
у = [у, копировать.deepcopy(у)]
print(y) # [[0, 0], [0, 0]]
у [0] [0] = 1
print(y) # [[1, 0], [0, 0]]
 

еще один интересный способ создания клонированных копий, Операция 4:

 импортировать копию
у = [0] * 2
напечатать(у) # [0, 0]
y = [copy. deepcopy(y) для числа в диапазоне (1,5)]
print(y) # [[0, 0], [0, 0], [0, 0], [0, 0]]
у [0] [0] = 5
print(y) # [[5, 0], [0, 0], [0, 0], [0, 0]]
 

С помощью встроенной функции списка вы можете сделать так

 a
выход:[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
#Отображение списка
а.удалить(а[0])
выход:[[1, 1, 1, 1], [1, 1, 1, 1]]
# Удален первый элемент списка, в котором нужно изменить номер
а. добавить ([5,1,1,1])
выход:[[1, 1, 1, 1], [1, 1, 1, 1], [5, 1, 1, 1]]
# добавляем элемент в список, но добавленный элемент, как вы можете видеть, добавляется последним, но вы хотите, чтобы он начинался
а.обратный()
выход:[[5, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
#Итак, наконец, переверните весь список, чтобы получить желаемый список
 
1

Я пришел сюда, потому что хотел посмотреть, как можно вложить произвольное количество списков. Выше есть много объяснений и конкретных примеров, но вы можете обобщить N-мерный список списков списков … с помощью следующей рекурсивной функции:

 import copy
def list_ndim (dim, el = None, init = None):
    если инициализация отсутствует:
        инициализация = эль
    если len(dim)> 1:
        return list_ndim(dim[0:-1], None, [copy. copy(init) для x в диапазоне(dim[-1])])
    return [copy.deepcopy(init) для x в диапазоне(dim[0])]
 

Вы делаете свой первый вызов функции следующим образом:

 dim = (3,5,2)
эл = 1,0
л = list_ndim (тусклый, эл)
 

, где (3,5,2) — это кортеж размеров структуры (аналогично аргументу numpy shape ), а 1.0 — это элемент, которым вы хотите инициализировать структуру (работает с None также). Обратите внимание, что аргумент init предоставляется только рекурсивным вызовом для переноса вложенных дочерних списков

вывода выше:

 [[[1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0]],
 [[1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0]],
 [[1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0]]]
 

набор конкретных элементов:

 l[1][3][1] = 56
л[2][2][0] = 36,0+0,0j
л[0][1][0] = 'абв'
 

результирующий вывод:

 [[[1.0, 1.0], ['abc', 1. 0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0]],
 [[1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 56.0], [1.0, 1.0]],
 [[1.0, 1.0], [1.0, 1.0], [(36+0j), 1.0], [1.0, 1.0], [1.0, 1.0]]]
 

нетипизированный характер списков продемонстрирован выше

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

 node_count = 4
цвета = [0,1,2,3]
sol_dict = {узел: цвета для узла в диапазоне (0, node_count)}
 

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

 >>> sol_dict
{0: [0, 1, 2, 3], 1: [0, 1, 2, 3], 2: [0, 1, 2, 3], 3: [0, 1, 2, 3]}
>>> [v — это цвета для v в sol_dict.values()]
[Правда, правда, правда, правда]
>>> sol_dict[0].remove(1)
>>> sol_dict
{0: [0, 2, 3], 1: [0, 2, 3], 2: [0, 2, 3], 3: [0, 2, 3]}
 

Правильный способ создания словаря — использовать копию списка для каждого значения.

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

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