Каков самый быстрый способ доступа к элементам во вложенном списке?


У меня есть список, состоящий из трех слоев, который выглядит примерно так для иллюстрации:

a = [[['1'],['2'],['3'],['']],[['5'],['21','33']]]
Таким образом, у меня есть верхний список, который содержит несколько других списков, каждый из которых снова содержит списки. Первый слой будет содержать десятки списков. Следующий слой может содержать, возможно, миллионы списков, а нижний слой будет содержать либо пустую строку, либо одну строку, либо несколько значений (каждая строка).

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

Я могу придумать два способа:

  1. я обращаюсь к списку a напрямую, чтобы получить желаемое значение, например a[1][1][0] вернет '21'.
  2. я создаю копию элементов a , а затем доступ к ним, чтобы сгладить список немного больше. В этом случае таким образом, напр.: b=a[0], c=a[1] поэтому вместо того, чтобы обращаться к a[1][1][0], я бы теперь обратился к b[1][0], чтобы получить '21'.

Существует ли какое-либо ограничение производительности, связанное с доступом к вложенным спискам? Таким образом, есть ли какая-то выгода в разделении списка a на отдельные списки или я просто несу за это штраф RAM?

2 2

2 ответа:

Эти два метода более или менее идентичны, учитывая, что b=a[0] только связывает другое имя со списком в этом индексе. Он не копирует список. Тем не менее, единственная разница заключается в том, что в вашем втором методе единственная разница заключается в том, что вы, в дополнение к доступу к вложенным спискам, вы в конечном итоге бросаете ссылки вокруг. Так что, теоретически, это немного медленнее.

Как указывает @joaquinlpereyra, Python Wiki имеет список сложности таких операций: https://wiki.python.org/moin/TimeComplexity

Итак, длинный ответ прерван: просто доступ к элементам списка быстрее.

Доступ к элементам через их индекс (т. е.[1][1][0]) является операцией O (1): Источник . Вы не получите намного быстрее, чем это.

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