Диапазон поворота Python 3 к списку

178

Я пытаюсь составить список с числами 1-1000в нем. Очевидно, что это было бы неприятно писать / читать, поэтому я пытаюсь составить список с диапазоном в нем. В Python 2 кажется, что:

some_list = range(1,1000)

сработало бы, но в Python 3 диапазон похож на xrangePython 2?

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

навес для лодок
источник
1
Кроме того, some_list[i] == i+1так что, вероятно, вам все равно не нужен список.
njzk2
1
@RikPoggi. например, может потребоваться предоставить список для функции построения графиков. Иногда может быть достаточно диапазона, но диапазон не может быть объединен (является неизменным), поэтому, если вам нужно добавить начальное значение по умолчанию для всех построенных списков, его также необходимо превратить в список.
SherylHohman

Ответы:

223

Вы можете просто построить список из объекта диапазона:

my_list = list(range(1, 1001))

Вот как вы это делаете с генераторами в python2.x. Говоря в общем, вам, вероятно, не нужен список, поскольку вы можете получить значение my_list[i]более эффективно ( i + 1), и если вам просто нужно перебрать его, вы можете просто вернуться к нему range.

Также обратите внимание, что на python2.x xrangeвсе еще индексируется 1 . Это означает, что rangeна python3.x тоже есть свойство 2

1print xrange(30)[12] работает для python2.x

2 Аналогичное утверждение для 1 в python3.x есть print(range(30)[12])и это тоже работает.

mgilson
источник
4
Это, безусловно, путь, но придирка: это на самом деле не «актерский состав»
jterrace
@jterrace изменил «cast» на «convert». Ты прав насчет того, что ты не актёрский состав ... Я не знаю, как это точно назвать.
Мгилсон
2
Я бы сказал «конструировать» или «строить» (или, возможно, «материализовать») - поскольку вы не «конвертируете» (как таковой) генератор в список, вы создаете новый объект списка из источника данных, который происходит быть генератором ... (но я могу просто раскалывать волосы и не на 100% быть уверенным в том, что мне нравится в любом случае)
Джон Клементс
2
Мой +1 за "конструировать", поскольку это согласуется с другими языками ОО. В list(arg)других языках это называется вызовом конструктора listкласса. На самом деле, это также случай с Python. Споры о том, заполнен ли объект во время конструирования (как в случае C ++) или только во время первого автоматически вызываемого метода (как в __init__()методе Python ), не могут изменить основную абстрактную идею. На мой взгляд, конструктор списка берет итератор и заполняет список возвращаемыми значениями .
pepr
2
Почему выдает ошибку в ноутбуке jupyter и нормально работает в оболочке? Ошибка:'range' object is not callable
поисковик
34

В Pythons <= 3.4 вы можете, как другие предложили, использовать list(range(10)), чтобы составить список из диапазона (в общем, любой повторяемый).

Другая альтернатива, представленная в Python 3.5с его распаковывающими обобщениями, заключается в использовании *в списке литерала []:

>>> r = range(10)
>>> l = [*r]
>>> print(l)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Хотя это эквивалентно list(r), это буквальный синтаксис, и тот факт, что вызов функции не задействован, позволяет выполнять его быстрее. Это также меньше символов, если вам нужно код гольф :-)

Димитрис Фасаракис Хиллиард
источник
4
Чтобы быть понятным, вы все еще можете написать в одну строку: [*range(10)]прекрасно работает, когда вам не нужно rangeни для каких целей, кроме инициализации list. Примечание: моя любимая (хорошо, не совсем) часть распаковывающих обобщений состоит в том, что пустые sets теперь имеют буквальный синтаксис {*()}, или, как я это называю, оператор одноглазой обезьяны. ;-)
ShadowRanger
@ShadowRanger - вот как я изначально думал о написании этого. Я решил быть немного более многословным, чтобы не запутывать новых пользователей Python :-)
Dimitris Fasarakis Hilliard
26

в Python 3.x range()функция получила свой собственный тип. так что в этом случае вы должны использовать итератор

list(range(1000))

nurulhudamustaqim
источник
11
"в этом случае вы должны использовать итератор"? Что, черт возьми, это должно означать?
user2357112 поддерживает Monica
2
Я использую Python 3.7 и пробовал x = list (range (1000)), но получил ошибку TypeError: объект list не вызывается
Earthshaker
@Earthshaker У тебя должна быть опечатка, какlist(range(1000))()
wjandrea
17

Причина, по которой Python3 не имеет функции для непосредственного получения ранжированного списка, заключается в том, что оригинальный дизайнер Python3 был довольно новичком в Python2. Он рассматривал только использование range()функции в цикле for, поэтому список никогда не нужно расширять. На самом деле, очень часто нам нужно использовать range()функцию для создания списка и передачи в функцию.

Следовательно, в этом случае Python3 менее удобен по сравнению с Python2, потому что:

  • В Python2 у нас есть xrange()и range();
  • В Python3 у нас есть range()иlist(range())

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

[*range(N)]
xuancong84
источник
3
Весь смысл в том, чтобы сделать его менее удобным list, потому что обычно это неправильно. Для 99 из 100 вариантов использования создание факта listнеэффективно и бессмысленно, поскольку rangeсамо по себе действует как неизменяемая последовательность почти во всех отношениях, иногда более эффективно при загрузке (например, тесты содержания для ints являются O(1), а не O(n)для lists). В Python 2 люди предпочитали использовать rangeпо умолчанию, хотя это xrangeбыл почти всегда лучший вариант; в Python 3 вы можете явно включить list, а не случайно получить его, используя неправильное имя.
ShadowRanger
7
Комментарий о дизайнере Python 3 и его опыте в Python 2 довольно смелый и дерзкий.
Казарей
@kazarey Но правда ли это? В Python есть много вещей, которые вызывают сомнения в этом отношении
Джавадба
1
Было бы одобрение, особенно для распаковки-сокращения для создания списка, но я согласен с @kazarey. Комментарий о дизайнере является как необоснованным (или, по крайней мере, без ссылок), так и ненужным.
Нубарке
12

Вам действительно не нужно использовать цифры 1-1000 в списке. Но если по какой-то причине вам действительно нужны эти цифры, то вы можете сделать:

[i for i in range(1, 1001)]

Понимание списка в двух словах:

Вышеприведенное понимание списка означает:

nums = []
for i in range(1, 1001):
    nums.append(i)

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

Диапазон начинается с первого параметра; но заканчивается до, не включая второй параметр (когда задано 2 параметра; если первый параметр пропущен, он будет начинаться с «0»)

range(start, end+1)
[start, start+1, .., end]
inspectorG4dget
источник
20
Почему понимание? Просто:list(range(1000))
Рик Поджи
Спасибо! Не могли бы вы объяснить, почему я для меня, а не просто для меня?
Эллинг
Я не работал с python3. Так что я не совсем уверен, как это работает. Я знаю, что понимание будет работать, но не было 100% на кастинге. Но если кастинг работает, то вы правы, и ваш путь более питоничен.
inspectorG4dget
1
@ inspectorG4dget: это не «приведение», это вызов list()конструктора с итерацией . list()Конструктор знает , как создать новый список , когда данный объект любой итерации.
Грег Хьюгилл
4
@ list(range(1000))inspectorG4dget : будет работать в python3 так же, как и list(xrange(1000))в python2
Рик Поджи
4

На самом деле, если вы хотите 1-1000 (включительно), используйте range(...)функцию с параметрами 1 и 1001: range(1, 1001)потому что range(start, end)функция переходит от начала к (конец-1) включительно.

CosmicComputer
источник
0

Используйте Range в Python 3.

Вот пример функции, которая возвращает число между двумя числами

def get_between_numbers(a, b):
    """
    This function will return in between numbers from two numbers.
    :param a:
    :param b:
    :return:
    """
    x = []
    if b < a:
        x.extend(range(b, a))
        x.append(a)
    else:
        x.extend(range(a, b))
        x.append(b)

    return x

результат

print(get_between_numbers(5, 9))
print(get_between_numbers(9, 5))

[5, 6, 7, 8, 9]  
[5, 6, 7, 8, 9]
Раджив Шарма
источник
Кажется, это ответ на другой вопрос ...?
wjandrea
-1

Фактически, это ретро-градация Python3 по сравнению с Python2. Конечно, Python2, который использует range () и xrange (), более удобен, чем Python3, который использует list (range ()) и range () соответственно. Причина в том, что первоначальный разработчик Python3 не очень опытен, они рассматривали только использование функции range многими новичками для итерации по большому количеству элементов, в которых неэффективны как память, так и процессор; но они пренебрегали использованием функции диапазона для создания списка номеров. Теперь им уже поздно возвращаться.

Если бы я был дизайнером Python3, я:

  1. используйте irange для возврата итератора последовательности
  2. используйте lrange для возврата списка последовательностей
  3. используйте диапазон для возврата итератора последовательности (если количество элементов велико, например, диапазон (9999999), или списка последовательностей (если количество элементов мало, например, диапазон (10))

Это должно быть оптимальным.

xuancong84
источник
Как это отвечает на вопрос?
wjandrea
Да, он отвечает на вопрос, предлагая разработчикам Python3 изменить и улучшить Python3. Но маловероятно, что они изменятся, поскольку они не настолько элегантны.
xuancong84