Làm cách nào để chuyển đổi chuỗi thành số nguyên trong Python?


438

Tôi có một bộ dữ liệu từ một truy vấn MySQL như thế này:

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

Tôi muốn chuyển đổi tất cả các thành phần chuỗi thành số nguyên và đưa chúng trở lại danh sách các danh sách:

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

Tôi đã cố gắng để đạt được nó evalnhưng chưa nhận được kết quả tốt.


2
Có lẽ xem xét một mô-đun bộ chuyển đổi cơ sở dữ liệu khác nhau? Tôi biết các mô-đun bộ điều hợp PostgreSQL sẽ trả về kết quả như bộ T2 của bạn.
kquinn

3
Bản sao có thể có của Parse String to Float hoặc Int
Nathan

xin lưu ý: khi sử dụng bản đồ, bạn sẽ nhận được một danh sách các đối tượng bản đồ trong python 3 và 3.5. Điều này làm điều đó cho Python 3.5 như đã đề cập ở trên. new_list = list (list (int (a) for a in b) for b in T1 if a.itorigit ())
Khách

Câu hỏi tương tự cho danh sách không lồng nhau: Chuyển đổi tất cả các chuỗi trong danh sách thành int
Aran-Fey

Câu trả lời:


630

int()là hàm dựng sẵn tiêu chuẩn Python để chuyển đổi một chuỗi thành một giá trị nguyên. Bạn gọi nó với một chuỗi chứa một số làm đối số và nó trả về số được chuyển đổi thành một số nguyên:

print (int("1") + 1)

Các bản in trên 2.

Nếu bạn biết cấu trúc danh sách của mình, T1 (chỉ đơn giản là nó chứa các danh sách, chỉ có một cấp độ), bạn có thể làm điều này trong Python 2:

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

Trong Python 3:

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

4
tại sao không T2 = map(lambda lol: map(int, lol), T1)? Cả bản đồ hoặc danh sách hiểu, cả hai đều ngớ ngẩn;)
cừu bay

4
@flyingsheep Bản đồ đôi có vẻ ngớ ngẩn với tôi, điều này có vẻ tốt.
jamylak

Làm thế nào về việc loại bỏ ví dụ Python 2 (vì hết tuổi thọ cho Python2)?
Alisso

28

Bạn có thể làm điều này với một sự hiểu biết danh sách:

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

Danh sách sự hiểu biết bên trong ( [int(column) for column in row]) xây dựng một listsố ints từ một chuỗi các intđối tượng -able, giống như chuỗi số thập phân, trong row. Khả năng hiểu danh sách bên ngoài ( [... for row in T1])) xây dựng một danh sách các kết quả của việc hiểu danh sách bên trong được áp dụng cho từng mục trong T1.

Đoạn mã sẽ thất bại nếu bất kỳ hàng nào chứa các đối tượng không thể được chuyển đổi theo int. Bạn sẽ cần một hàm thông minh hơn nếu bạn muốn xử lý các hàng có chứa các chuỗi không thập phân.

Nếu bạn biết cấu trúc của các hàng, bạn có thể thay thế việc hiểu danh sách bên trong bằng một cuộc gọi đến một chức năng của hàng. Ví dụ.

T2 = [parse_a_row_of_T1(row) for row in T1]

16

Tôi muốn sử dụng danh sách chỉ hiểu:

[[int(y) for y in x] for x in T1]

12

Thay vì đặt int( ), đặt float( )sẽ cho phép bạn sử dụng số thập phân cùng với số nguyên.


2
Bạn có thể giải thích chi tiết hơn về câu trả lời của bạn?
Rico

10

Tôi đồng ý với câu trả lời của mọi người cho đến nay nhưng vấn đề là nếu bạn không có tất cả các số nguyên thì họ sẽ gặp sự cố.

Nếu bạn muốn loại trừ những người không có số nguyên thì

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

Điều này chỉ mang lại chữ số thực tế. Lý do tôi không sử dụng hiểu danh sách trực tiếp là vì hiểu danh sách rò rỉ các biến nội bộ của chúng.


2
isdigitlà khó khăn, hãy thử nó -1. int(<str>)là cách để kiểm tra bởi 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

7
Chào mừng bạn đến với Stack Overflow! Thay vì chỉ đăng một khối mã, vui lòng giải thích lý do tại sao mã này giải quyết vấn đề được đặt ra. Không có lời giải thích, đây không phải là một câu trả lời.
Artemix

7

Thử cái này.

x = "1"

x là một chuỗi bởi vì nó có dấu ngoặc kép xung quanh nó, nhưng nó có một số trong đó.

x = int(x)

Vì x có số 1 trong đó, tôi có thể biến nó thành số nguyên.

Để xem nếu một chuỗi là một số, bạn có thể làm điều này.

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)

Nó nên in ra IDLE True vì x là một số.

y_test = is_number(y)

print(y_test)

Nó sẽ in ra IDLE Sai vì y không phải là số.


2
Hàm is_number của bạn sai. '1' không bằng 1. Đây không phải là Perl. :-P
Veky

3
Đừng phát minh lại bánh xe, sử dụng x.isnumeric().
bfontaine

4

Sử dụng hiểu danh sách:

t2 = [map(int, list(l)) for l in t1]

1
trong python 3, điều này trả về một danh sách các đối tượng bản đồ :(
CpILL

3

Trong Python 3.5.1, những thứ như thế này hoạt động:

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

Enter number:  4.7
4
5

George.


3

Xem chức năng này

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

Sau đó

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

Bạn cũng có thể kiểm tra

if val == None:  # True if input value can not be converted
    pass  # Note: Don't use 'if not val:'

evallà xấu xa: bạn nên thay thế nó bằng ast.literal_eval.
Eli Korvigo

3

Một giải pháp chức năng khác cho Python 2:

from functools import partial

map(partial(map, int), T1)

Python 3 sẽ hơi lộn xộn một chút:

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

chúng ta có thể khắc phục điều này bằng một trình bao bọc

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

oldmap(partial(oldmap, int), T1)

1

Nếu nó chỉ là một tuple, một cái gì đó giống như rows=[map(int, row) for row in rows]sẽ làm điều đó. (Có một sự hiểu biết danh sách và một cuộc gọi đến bản đồ (f, lst), tương đương với [f (a) cho a trong lst], trong đó.)

Eval không phải là những gì bạn muốn làm, trong trường hợp có một cái gì đó giống như __import__("os").unlink("importantsystemfile")trong cơ sở dữ liệu của bạn vì một số lý do. Luôn xác thực đầu vào của bạn (nếu không có gì khác, ngoại lệ int () sẽ tăng nếu bạn có đầu vào xấu).


-1

Bạn có thể làm một cái gì đó như thế này:

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)  

-1

Tôi muốn chia sẻ một tùy chọn có sẵn mà dường như chưa được đề cập ở đây:

rumpy.random.permutation(x)

Sẽ tạo ra một hoán vị ngẫu nhiên của mảng x. Không chính xác những gì bạn yêu cầu, nhưng nó là một giải pháp tiềm năng cho các câu hỏi tương tự.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.