2015-09-03 3 views
2

У меня есть безобидный список «mylist» из шести предметов. Никогда не пустейте, никогда никаких зверских предметов.Как использовать переменные для нарезки списков Python?

mylist = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'] 

Я обнаружил, что есть два способа индексирования списка для целей нарезки. По этому вопросу я буду называть их верхний индекс (от 0 до 5) и нижний индекс (от -1 до -6). Вот краткая схема (я разместил фото с цветами, который был заменен другим пользователем):

<<<<|_________mylist[5:?:-1]_____________| 

    |___mylist[0:3:1]______|>>>>>> 
? 
(x) 0  1  2  3  4  5  (6) 

    aaa bbb ccc ddd eee fff 

(-7) -6  -5  -4  -3  -2  -1  (y) 
               ? 
      <<<<<<|___mylist[-1:-5:-1]___| 

    |______mylist[-6:?:1]________________|>>>>> 

Для легко нарезки в начале моего списка, я могу использовать верхний индекс, как это:

>>> mylist[0:3:1] 
['aaa', 'bbb', 'ccc'] 

для легко нарезки ближе к концу, я считаю, нижний индекс полезен, как:

>>> mylist[-1:-5:-1] 
['fff', 'eee', 'ddd', 'ccc'] 

Под «легко» Я имею в виду, например, аспект не касаясь моим кода с длиной списка.

Я узнал, что нарезка Python «всегда сдерживается» (также известная как «до, но не включая»). Я показываю это на диаграмме как «стрелочные головки», указывающие от конца среза до «следующего пункта» вперед («впереди» в смысле/направлении срезания).

Для моих пользователей мне нужно показать первое множество предметов из моего списка. (Это результаты рекурсивного поиска и оценки и сортировки.) Поскольку обычно этот список довольно длинный, я печатаю его назад (в консоли), так что, когда сценарий заканчивается, лучшие результаты n будут по-прежнему быть видимым на экране. Итак, мой шаг -1 в этом контексте.

Я хотел бы использовать переменные, чтобы обеспечить разные потребности для разных пользователей (и различные размеры экрана). Для отладки и для определенных пользователей я хочу иметь возможность распечатывать все результаты, т. Е. Весь список назад. Я хотел бы что-то в этом синтаксисе:

start = 5  # I only need to know "5" for debugging, normally I can use 
       # any small number to show a few selected items of mylist 

end = x  # this is my main question, see photo 

mylist[start:end:-1] 

Мой вопрос, пожалуйста, как я пишу первый (верхний) фрагмент в диаграмме, с помощью переменных и с помощью верхнего списка из индексы? Или, другими словами, Каково числовое значение xy) на диаграмме?

Semi-решения, которые я не хочу использовать:

mylist[5::-1]  # no variable at all 

mylist[5:None:-1] # does not fit in my normal function for printing 

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

end = None - 20 
TypeError: unsupported operand type(s) for -: 'NoneType' and 'int' 

И мне не удалось преобразовать None в любое целое или другое число. Есть ли способ? Вероятно, это будет святотатство в Pythonland ...

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

mylist[-1:-7:-1] # I want to use the upper index rather 

Но этот подход включает в себя проверку длины mystring.

end = -1 * (len(mystring)+1) # extra-explicit as an example 
returns -7 

mystring[-1:end:-1] 

returns ['fff', 'eee', 'ddd', 'ccc', 'bbb', 'aaa'] # this is the output I want, just not the method 

То, что я сделал, прежде чем спросить вас:
Я написал тестирование-скрипт и попытался угадыванием x. Я искал и читал много о разрезании и переменных здесь, в Stack Overflow (например, when use negative number to slice a string in Python, 0 is disabled?) и в Интернете (например, https://docs.python.org/3/library/functions.html?highlight=slice#slice), и я искал в электронных книгах, таких как Знакомство с Python и Learning Python.

Отвод:
Пожалуйста, не говори мне, что я хочу, это не так. Я могу нарезать mylist[0:6:1], хотя в моем списке примеров нет индекса 6, то же самое для -7. Вот почему у меня есть такая догадка, что могут быть цифры для x и для y тоже, которые я мог бы использовать в своих переменных.

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

Фон для тех, кто хочет больше:
Этот вопрос больше о «выяснить нарезку», чем о том, чтобы распечатка возможно. У меня есть обходные пути, но хотелось бы узнать больше.

+1

... какой ?! Вы хотите сказать, что вы хотите, чтобы первые элементы 'n' вашей последовательности, в обратном порядке? Почему бы не 'seq [: n] [:: - 1]' (т. Е. Получить первые элементы 'n', * then * отменить их - обратите внимание, что вы можете оставить некоторые из чисел, например, http: // stackoverflow. ком/кв/509211/3001761)? И можете ли вы передать контент с фотографии на фактический текст, пожалуйста; первый является крайне бесполезным для пользователей, например, . экранных – jonrsharpe

+0

@jonrsharpe: спасибо, да, первые n элементов обычно, а иногда и все предметы, и всегда наоборот. Я не понимаю, как «отказ от некоторых чисел» поможет мне использовать переменные - мой вопрос не в том, чтобы набирать меньше кода; пожалуйста, объясни. –

+0

@jonrsharpe: У вас есть ссылка на некоторую синтаксическую справку для создания моего графика в тексте, сохранения выравниваний и цветов и стрелок и т. Д.? Как это будет читать считыватель экрана?Есть ли у вас примеры, которые вы считаете хорошими или полезными? Я готов учиться, хотя я потратил много времени на мой вопрос, чтобы понять, что у меня есть и что я ищу. Существует ли правило, что вопросы должны быть доступны для максимального количества пользователей (или всех пользователей?), Включая те, у которых есть специальные настройки? –

ответ

1

Если я понял ваш вопрос правильно, вы хотите у такие, что

mylist[2:y:-1] == ['ccc', 'bbb', 'aaa'] 

где у должно быть целым числом.

y Вы ищете -len(mylist)-1 или нижнее целое число. Если вам нужна константа, вы можете использовать -sys.maxsize (так как невозможно иметь списки, превышающие maxsize).


Если посмотреть на исходный код CPython, мы можем видеть, что list objects internally use the function PySlice_GetIndicesEx. Чтобы сделать то, что вы хотите, PySlice_GetIndicesEx должен установить step = -1, start = 2 и slicelength = 3.

start = 2 и Шаг = -1 уже настроены с помощью кода. Имеются ли значения для y, которые могут привести к slicelength = 3? Давайте посмотрим ...

Когда шаг отрицательна, то линия, которая вычисляет slicelength является this one:

*slicelength = (*stop-*start+1)/(*step)+1; 

Отсюда мы видим, что для того, чтобы иметь slicelength = (остановка - start + 1)/step + 1 = 3, мы должны иметь stop = -1. Тем не менее, the case stop < 0 is treated specially:

if (*stop < 0) *stop += length; 
if (*stop < 0) *stop = (*step < 0) ? -1 : 0; 

Таким образом, если мы обеспечиваем отрицательную остановку, он получает увеличился на len(mylist). Если stop все еще отрицательный, он установлен на -1, который является нужной нам величиной.

+0

удивительный. Очень опасно заявлять, что не существует никакого решения для данного вопроса с его конкретным контекстом (и вы серьезно относитесь к моему усмотрению о синтаксисе разрезания). Таким образом, ваш подход, чтобы посмотреть на источник и то, как вы ясно показываете его не-разработчикам, очень полезно.Я боялся, что ответа нет, и я рад, что я не просто что-то пропустил. Я надеялся на какой-то встроенный скрытый «псевдоним» или что-то еще, как те, что существуют на языках, и обычно нужно сказать; трудно догадаться об этом. –

+0

@MartinZaske: Я обновил ответ. Вероятно, он содержит нужное вам решение, хотя я не уверен. –

+0

Я не критиковал ваше первоначальное вступительное заявление, а скорее дополнял вас. Врач никогда не может сказать: «У тебя нет болезни». или «Нет никакого лечения для этого». но математик может сказать: «Нет решения». когда он сможет это доказать. Еще раз спасибо за предоставление доказательств. –

4

Короткий ответ: No.


Вы должны использовать None, если вы не хотите, чтобы вычислить длину списка (хотя это O(1) операция в Python):

>>> mylist = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'] 
>>> mylist[2:None:-1] # first 3 items backwards (note off-by-one indexing) 
['ccc', 'bbb', 'aaa'] 
>>> mylist[None:None:-1] # all items backwards 
['fff', 'eee', 'ddd', 'ccc', 'bbb', 'aaa'] 

Вы могли использовать заполнитель для «все это», например 0:

>>> end = 3 
>>> mylist[end - 1 if end else None::-1] 
['ccc', 'bbb', 'aaa'] 
>>> end = 0 
>>> mylist[end - 1 if end else None::-1] 
['fff', 'eee', 'ddd', 'ccc', 'bbb', 'aaa'] 

Вы также могли бы рассмотреть два шага, то есть взять кусок вы хотите затем повернуть его вспять:

>>> mylist[:3][::-1] 
['ccc', 'bbb', 'aaa'] 
+0

Да, никто не самый близкий я сам пришел, как я написал в своем вопросе. Я просто не могу сделать с ней ничего математического, как я могу с целыми числами в переменных. Вот почему я спросил, есть ли число или числовой эквивалент (или альтернативное выражение) для None. По крайней мере, я могу назначить None своей конечной переменной, так что это один шаг к хорошему решению. –

+0

@MartinZaske, тогда ответ: * «нет» *. Честно говоря, я думаю, что вы, возможно, слишком усложнили то, что по сути является простым вопросом, делая его намного сложнее, чем нужно, чтобы отвечать. – jonrsharpe

+0

@MartinZaske Я предполагаю, что могу использовать фиктивное значение (скажем, использовать '0' для *" всех элементов "*), то есть, например, 'mylist [end - 1 if end else 0 :: - 1]'. Также неясно, в чем проблема с отсутствием значений. – jonrsharpe

1

Просто сделайте значение по умолчанию, и если пользователь изменяет значение по умолчанию (max), то измените свою переменную.

>>> mylist = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'] 
>>> display_num = len(mylist) 
>>> mylist[display_num-1::-1] 
['fff', 'eee', 'ddd', 'ccc', 'bbb', 'aaa'] 

Измените переменную display_num на количество результатов, которые вы хотите отобразить.

>>> display_num = 4 
>>> mylist[display_num-1::-1] 
['ddd', 'ccc', 'bbb', 'aaa'] 

Я думаю, что ваши варианты: None или length of list.

... или просто использовать попробовать поймать

>>> display_num = None 
>>> try: 
>>>  mylist[display_num-1::-1] 
>>> except TypeError: 
>>>  mylist[::-1] 
+0

Мне нравится ваша помощь с фактическими примерами того, как с ней справиться. И я замечаю, что вы всегда оставляете «критическое место» (конец ломтика) пустым, как в :: Может быть, ваш косвенный способ сказать «Нет ли числового псевдонима для None в контексте перебора списков Python»? –