Функція виклику int () для кожного елемента списку?


184

У мене є список з числовими рядками, наприклад:

numbers = ['1', '5', '10', '8'];

Я хотів би перетворити кожен елемент списку в ціле число, так це виглядатиме так:

numbers = [1, 5, 10, 8];

Я міг би це зробити за допомогою циклу, наприклад:

new_numbers = [];
for n in numbers:
    new_numbers.append(int(n));
numbers = new_numbers;

Чи повинно бути так потворно? Я впевнений, що існує більш пітонічний спосіб зробити це в одному рядку коду. Будь ласка, допоможіть мені.


1
Яку версію Python ви використовуєте?
Марк Байєрс

Відповіді:



131

У Python 2.x інший підхід полягає у використанні map:

numbers = map(int, numbers)

Примітка: у Python 3.x mapповертається об’єкт карти, який ви можете перетворити у список, якщо хочете:

numbers = list(map(int, numbers))

11
У Python 3.x mapповертає ітератор замість списку, тому його потрібно записати так, list(map(int, numbers))ніби потрібен список.
kennytm

2
Я думаю, що зараз підхід до розуміння списку є дещо прихильнішим.
екстранеон

3
@extraneon: Так ... або, можливо, подумайте про використання генератора замість списку, залежно від того, для чого ви його будете використовувати. Перевага генератора полягає в тому, що якщо вам, можливо, не потрібно буде дивитися на всі елементи, то вам не доведеться витрачати час на їх обчислення заздалегідь.
Марк Байєрс

4
Виміряно часом з Python 2.7.2: LC: 3.578153133392334, карта: 4.9065070152282715
AJJ

1
@AJJ: mapмає більш високі накладні витрати, але у довідковому інтерпретаторі, якщо функція перетворення - це вбудована функція Python, реалізована в C, вона має меншу вартість на предмет. Тестування на введенні лише чотирьох значень не дасть корисної інформації про масштабування. Це сказано, що в моїх власних тестах (на Py2.7.12 та Py3.5.2, останній з list()обгорткою), Py2 з win mapнавіть за чотири вхідні елементи і програє лише невеликим запасом на Py3; Я підозрюю, що ваші тести були викривлені на користь списків.
ShadowRanger

21

просто крапка,

numbers = [int(x) for x in numbers]

розуміння списку є більш природним, тоді як

numbers = map(int, numbers)

швидше.

Напевно, це не матиме значення в більшості випадків

Корисне читання: LP проти карти


6
Чи не повинно бути це число = map (int, number)?
Каран

9

Якщо ви маєте намір передати ці цілі числа функції чи методу, розгляньте цей приклад:

sum(int(x) for x in numbers)

Ця конструкція навмисно надзвичайно схожа на списки розумінь, згаданих Адамом. Без квадратних дужок це називається генераторним виразом і є дуже ефективним способом передачі списку аргументів методу. Хороша дискусія доступна тут: Генераторні вирази проти списку


4

Ще один спосіб зробити це в Python 3:

numbers = [*map(int, numbers)]


1
Чи можете ви пояснити це? Я не знайомий із цим синтаксисом. Дякую!
abalter

1
Я використовую список розпакування аргументів ( docs.python.org/3/tutorial/… )
zhukovgreen

Ага, пітон 3 річ. Дивно здається, що []взяти аргумент список. І я не знав, що ви можете передати ітератор як список аргументів. Я б подумав зробити number = list(map(int, numbers)). Але дякую за пояснення!
abalter

3

Інший спосіб,

for i, v in enumerate(numbers): numbers[i] = int(v)

6
ОП заявила пітонічну
SilentGhost

3
Цей спосіб дуже корисний, якщо ви хочете виконати операцію лише на деяких елементах у списку. Це не стосується питання в цій темі, але можуть бути випадки, коли це корисно
Дікла

1

Думав, я б консолідував відповіді і показав деякі timeitрезультати.

Python 2 смокче в цьому досить погано, але mapтрохи швидше, ніж розуміння.

Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import timeit
>>> setup = """import random
random.seed(10)
l = [str(random.randint(0, 99)) for i in range(100)]"""
>>> timeit.timeit('[int(v) for v in l]', setup)
116.25092001434314
>>> timeit.timeit('map(int, l)', setup)
106.66044823117454

Python 3 закінчується в 4 рази швидше сам по собі, але перетворення mapоб’єкта генератора в список все ще швидше, ніж розуміння, а створення списку шляхом розпакування mapгенератора (дякую Артему!) Все ще трохи швидше.

Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 17:54:52) [MSC v.1900 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import timeit
>>> setup = """import random
random.seed(10)
l = [str(random.randint(0, 99)) for i in range(100)]"""
>>> timeit.timeit('[int(v) for v in l]', setup)
25.133059591551955
>>> timeit.timeit('list(map(int, l))', setup)
19.705547827217515
>>> timeit.timeit('[*map(int, l)]', setup)
19.45838406513076

Примітка: У Python 3 4 елементи, здається, є точкою перехрестя (3 у Python 2), де розуміння трохи швидше, хоча розпакування генератора все ж швидше, ніж для списків, що містять більше 1 елемента.

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