Python3 список фрагментов: указать c использовать в методе класса - PullRequest
1 голос
/ 03 февраля 2020

Я видел множество Python вопросов с фрагментами списка здесь, я не думаю, что я что-то дублирую, несмотря на то, что это затрагивает многие из тех же вопросов. Мой вопрос касается сокращения списка с использованием срезов, создания нового списка и обновления исходного списка.

Моя задача заключается в определении метода Class, который принимает два аргумента (word_list, num) и манипулирует word_list используя нарезку. Я продолжаю нарезать, пока word_list не станет пустым, сохраняя каждый срез в новом списке. Не важно, с какого конца я срезаю, с точки зрения содержания среза, но просто то, что я могу продолжать нарезку и вести точную запись событий.

Примите следующее:

word_list = ["once", "upon", "a", "time", "there", "lived", "an", "old", "man"]

sub_list1 = word_list[:2] # ["once", "upon"]
word_list = word_list[2:] # ["a", "time", "there", "lived", "an", "old", "man"]

сравните это с

word_list = ["once", "upon", "a", "time", "there", "lived", "an", "old", "man"]

sub_list2 = word_list[-2:] # ["old", "man"]
word_list = word_list[:-2] # ["once", "upon", "a", "time", "there", "lived"]

. В первом примере выше элементы списка «шунтируются» по мере взятия фрагментов, в отличие от второго, когда список просто укорачивается и ничто не «движется». Я придумываю проблему или есть какие-то фактические последствия для нарезки word_list по-другому?

Ответы [ 2 ]

2 голосов
/ 03 февраля 2020

Расширенный синтаксис срезов работает путем создания объекта slice для передачи в соответствующий метод __getitem__. foo[x:y:z] становится foo.__getitem__(slice(x, y, z)).

Нет никаких предположений относительно пропущенных значений; значение None просто передается в slice. Таким образом, ваши выражения становятся

word_list[:2]   -> word_list.__getitem__(slice(None, 2, None))
word_list[2:]   -> word_list.__getitem__(slice(2, None, None))
word_list[:-2]   -> word_list.__getitem__(slice(None, -2, None))
word_list[-2:]   -> word_list.__getitem__(slice(-2, None, None))

Решение о том, как обрабатывать каждое значение None, зависит от реализации __getitem__. Как правило, контекст принимается во внимание. Если шаг положительный, пропущенное начало рассматривается как 0; если он отрицательный, как -1. Пропущенный шаг обычно по умолчанию равен 1, независимо от начальной и конечной позиции; вот почему что-то вроде foo[10:0] пусто, а не предполагает, что вы хотите использовать шаг -1.

1 голос
/ 03 февраля 2020

не уверен, что понимаю вашу проблему, но я не вижу каких-либо реальных последствий между вашим первым и вторым примером, просто ваша интерпретация

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

import numpy as np
import struct
import sys

from simple_benchmark import BenchmarkBuilder
b = BenchmarkBuilder()

@b.add_function()
def positive_slicing(my_list):
    sub_list = my_list[:2]
    my_list = my_list[2:]

@b.add_function()
def negative_slicing(my_list):
    sub_list = my_list[-2:]
    my_list = my_list[:-2]

@b.add_arguments('slicing list')
def argument_provider():
    for exp in range(2, 7):
        size = 10**exp
        yield size, ['some random example'] * size

r = b.run()
r.plot()

enter image description here

...