Діапазон повороту 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])і воно також працює.


4
Це, безумовно, шлях, але нітпік: це насправді не "каст"
jterrace

@jterrace змінив "кинути" на "конвертувати". Ти маєш рацію про те, що він не є актором ... Я не знаю, як саме це назвати.
mgilson

2
Я б сказав "сконструювати" або "побудувати" (або можливо "матеріалізуватися") - оскільки ви не "перетворюєте" (як такий) генератор в список, ви створюєте новий об'єкт списку з джерела даних, що відбувається бути генератором ... (але з'єм просто розщеплювати волоски і не на 100% впевнений, що мені все одно вдається)
Джон Клементс

2
Мій +1 для "конструкту", як це відповідає іншим мовам ОО. list(arg)Розуміються в інших мовах , як виклик конструктора listкласу. Насправді, це теж випадок Python. Дебати, чи заповнюється об'єкт під час побудови (як у випадку C ++) або лише під час першого автоматично викликаного методу (як у __init__()методі Python ), не можуть змінити основну абстрактну думку. На мій погляд, конструктор списку бере ітератор і заповнює список поверненими значеннями .
пепр

2
Чому це дає помилку в зошиті з юпітером і працює добре в оболонці? Помилка:'range' object is not callable
subtleseeker

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))


11
"у цьому випадку ви повинні використовувати ітератор"? Що чорт має це означати?
user2357112 підтримує Monica

2
Я використовую Python 3.7 & пробував й = список (діапазон (1000)) , але отримав TypeError про помилку: «список» об'єкт не викликаний
Землекрушітель

@Earthshaker У вас має бути помилка list(range(1000))()
друку

17

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

Тому в цьому випадку Python3 є менш зручним порівняно з Python2, оскільки:

  • У Python2 ми маємо xrange()і range();
  • У Python3 у нас є range()іlist(range())

Тим не менш, ви все ще можете використовувати розширення списку таким чином:

[*range(N)]

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 дуже багато речей, які сумнівно ставляться до цих питань
javadba

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]

20
Чому розуміння? Просто:list(range(1000))
Рік Поггі

Дякую! Ви б не хотіли пояснити, чому це я за i in ... замість того, щоб я був?
Шлюпка

Я не працював з python3. Тож я не повністю впевнений у тому, як це працює. Я знаю, що розуміння спрацює, але не було на 100% на кастингу. Але якщо кастинг працює, то ти маєш рацію, а твій шлях більш пітонічний.
inspectorG4dget

1
@ inspectorG4dget: Це не "лиття", це викликає list()конструктор ітерабельним . list()Конструктор знає , як створити новий список , коли даний об'єкт будь-якої ітерації.
Грег Хьюгілл

4
@ inspectorG4dget: list(range(1000))буде працювати в python3 так само, як list(xrange(1000))у python2
Rik Poggi

4

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


0

Використовуйте діапазон в 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, який використовує список (range ()) та range () відповідно. Причина полягає в тому, що оригінальний дизайнер Python3 не дуже досвідчений, вони лише вважали використання функції діапазону багатьма новачками для перебору великої кількості елементів, де це і пам'ять, і процесор неефективні; але вони нехтували використанням функції діапазону для створення списку чисел. Тепер уже пізно, щоб вони вже змінилися.

Якби я став дизайнером Python3, я:

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

Це має бути оптимальним.


Як це відповідає на питання?
wjandrea

Так, він відповідає на питання, просячи розробників Python3 змінити та вдосконалити Python3. Але навряд чи вони зміняться, оскільки вони не такі витончені.
xuancong84
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.