Bagaimana cara mengubah string menjadi integer dengan Python?

438

Saya punya tupel tupel dari kueri MySQL seperti ini:

T1 = (('13', '17', '18', '21', '32'),
      ('07', '11', '13', '14', '28'),
      ('01', '05', '06', '08', '15', '16'))

Saya ingin mengubah semua elemen string menjadi bilangan bulat dan memasukkannya kembali ke daftar daftar:

T2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

Saya mencoba mencapainya evaltetapi belum mendapatkan hasil yang layak.

elfuego1
sumber
2
Mungkin mempertimbangkan modul adaptor basis data yang berbeda? Saya tahu modul adaptor PostgreSQL akan mengembalikan hasil seperti set T2 Anda.
kquinn
3
Kemungkinan duplikat Parse String to Float atau Int
Nathan
harap perhatikan: saat menggunakan peta, Anda akan mendapatkan daftar objek peta dengan python 3 dan 3.5. Ini melakukannya untuk Python 3.5 seperti yang disebutkan di atas. new_list = daftar (daftar (int (a) untuk a di b) untuk b di T1 jika a.isdigit ())
Tamu
Pertanyaan serupa untuk daftar yang tidak bersarang: Konversi semua string dalam daftar menjadi int
Aran-Fey

Jawaban:

630

int()adalah fungsi bawaan standar Python untuk mengubah string menjadi nilai integer. Anda menyebutnya dengan string yang berisi angka sebagai argumen, dan itu mengembalikan nomor yang dikonversi ke integer:

print (int("1") + 1)

Cetakan di atas 2.

Jika Anda mengetahui struktur daftar Anda, T1 (yang hanya berisi daftar, hanya satu tingkat), Anda bisa melakukan ini dengan Python 2:

T2 = [map(int, x) for x in T1]

Dengan Python 3:

T2 = [list(map(int, x)) for x in T1]
beristirahat
sumber
4
mengapa tidak T2 = map(lambda lol: map(int, lol), T1)? Entah peta atau daftar pemahaman, keduanya konyol;)
terbang domba
4
@flyingsheep Peta ganda tampaknya konyol bagi saya, ini sepertinya baik-baik saja.
jamylak
Bagaimana dengan menghapus contoh Python 2 (karena akhir hidup untuk Python2)?
Alisso
28

Anda dapat melakukan ini dengan pemahaman daftar:

T2 = [[int(column) for column in row] for row in T1]

Pemahaman daftar bagian dalam ( [int(column) for column in row]) membangun a listdari ints dari urutan intobjek -able, seperti string desimal, di row. Pemahaman daftar luar ( [... for row in T1])) membangun daftar hasil pemahaman daftar dalam yang diterapkan untuk setiap item di T1.

Cuplikan kode akan gagal jika salah satu baris berisi objek yang tidak dapat dikonversi oleh int. Anda akan membutuhkan fungsi yang lebih cerdas jika Anda ingin memproses baris yang berisi string non-desimal.

Jika Anda tahu struktur baris, Anda bisa mengganti pemahaman daftar dalam dengan panggilan ke fungsi baris. Misalnya.

T2 = [parse_a_row_of_T1(row) for row in T1]
Will Harris
sumber
16

Saya lebih suka menggunakan hanya daftar pemahaman:

[[int(y) for y in x] for x in T1]
odwl
sumber
12

Alih-alih menempatkan int( ), menempatkan float( )yang akan memungkinkan Anda menggunakan desimal bersama dengan bilangan bulat.

weir99
sumber
2
Bisakah Anda menjelaskan lebih detail tentang jawaban Anda?
Rico
10

Saya setuju dengan jawaban everyones sejauh ini tetapi masalahnya adalah bahwa jika Anda tidak memiliki semua bilangan bulat, mereka akan macet.

Jika Anda ingin mengecualikan yang bukan bilangan bulat maka

T1 = (('13', '17', '18', '21', '32'),
      ('07', '11', '13', '14', '28'),
      ('01', '05', '06', '08', '15', '16'))
new_list = list(list(int(a) for a in b) for b in T1 if a.isdigit())

Ini hanya menghasilkan digit aktual. Alasan saya tidak menggunakan pemahaman daftar langsung adalah karena pemahaman daftar bocor variabel internal mereka.

Christian Witts
sumber
2
isdigititu rumit, cobalah -1. int(<str>)adalah cara untuk memeriksa dengan try/ except.
totoro
9
T3=[]

for i in range(0,len(T1)):
    T3.append([])
    for j in range(0,len(T1[i])):
        b=int(T1[i][j])
        T3[i].append(b)

print T3
P.Hunter
sumber
7
Selamat Datang di Stack Overflow! Daripada hanya memposting blok kode, tolong jelaskan mengapa kode ini menyelesaikan masalah yang ditimbulkan. Tanpa penjelasan, ini bukan jawaban.
Artemix
7

Coba ini.

x = "1"

x adalah string karena memiliki tanda kutip di sekitarnya, tetapi ia memiliki angka di dalamnya.

x = int(x)

Karena x memiliki angka 1 di dalamnya, saya dapat mengubahnya menjadi bilangan bulat.

Untuk melihat apakah string adalah angka, Anda dapat melakukan ini.

def is_number(var):
    try:
        if var == int(var):
            return True
    except Exception:
        return False

x = "1"

y = "test"

x_test = is_number(x)

print(x_test)

Itu harus mencetak ke IDLE Benar karena x adalah angka.

y_test = is_number(y)

print(y_test)

Itu harus dicetak ke IDLE False karena y bukan angka.

TheRedstoneLemon
sumber
2
Fungsi is_number Anda salah. '1' tidak sama dengan 1. Ini bukan Perl. :-P
Veky
3
Jangan menemukan kembali roda, gunakan x.isnumeric().
bfontaine
4

Menggunakan pemahaman daftar:

t2 = [map(int, list(l)) for l in t1]
Jon
sumber
1
dalam python 3 ini mengembalikan daftar objek peta :(
CpILL
3

Dalam Python 3.5.1 hal-hal seperti ini berfungsi:

c = input('Enter number:')
print (int(float(c)))
print (round(float(c)))

dan

Enter number:  4.7
4
5

George.

George Moraitis
sumber
3

Lihat fungsi ini

def parse_int(s):
    try:
        res = int(eval(str(s)))
        if type(res) == int:
            return res
    except:
        return

Kemudian

val = parse_int('10')  # Return 10
val = parse_int('0')  # Return 0
val = parse_int('10.5')  # Return 10
val = parse_int('0.0')  # Return 0
val = parse_int('Ten')  # Return None

Anda juga bisa memeriksanya

if val == None:  # True if input value can not be converted
    pass  # Note: Don't use 'if not val:'
Shameem
sumber
evalitu jahat: Anda harus menggantinya dengan ast.literal_eval.
Eli Korvigo
3

Solusi fungsional lain untuk Python 2:

from functools import partial

map(partial(map, int), T1)

Python 3 akan sedikit berantakan:

list(map(list, map(partial(map, int), T1)))

kita bisa memperbaikinya dengan pembungkus

def oldmap(f, iterable):
    return list(map(f, iterable))

oldmap(partial(oldmap, int), T1)
Eli Korvigo
sumber
1

Jika itu hanya tupel tupel, sesuatu seperti rows=[map(int, row) for row in rows]akan melakukan trik. (Ada pemahaman daftar dan panggilan untuk memetakan (f, lst), yang sama dengan [f (a) untuk a in lst], di sana.)

Eval bukan yang ingin Anda lakukan, kalau-kalau ada sesuatu seperti __import__("os").unlink("importantsystemfile")dalam database Anda karena beberapa alasan. Selalu memvalidasi input Anda (jika dengan tidak ada yang lain, int pengecualian () akan naik jika Anda memiliki input yang buruk).

AKX
sumber
-1

Anda dapat melakukan sesuatu seperti ini:

T1 = (('13', '17', '18', '21', '32'),  
     ('07', '11', '13', '14', '28'),  
     ('01', '05', '06', '08', '15', '16'))  
new_list = list(list(int(a) for a in b if a.isdigit()) for b in T1)  
print(new_list)  
Amit Rawat
sumber
-1

Saya ingin membagikan opsi yang tersedia yang sepertinya belum disebutkan di sini:

rumpy.random.permutation(x)

Akan menghasilkan permutasi acak array x. Tidak persis seperti yang Anda minta, tetapi ini merupakan solusi potensial untuk pertanyaan serupa.

samvoit4
sumber