วิธีแปลงสตริงเป็นจำนวนเต็มใน Python


438

ฉันมี tuple ของ tuples จากแบบสอบถาม MySQL เช่นนี้

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

ฉันต้องการแปลงองค์ประกอบสตริงทั้งหมดให้เป็นจำนวนเต็มและนำกลับไปเป็นรายการ:

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

ฉันพยายามทำให้สำเร็จevalแต่ก็ยังไม่ได้ผลลัพธ์ที่ดีเลย


2
อาจพิจารณาโมดูลอะแดปเตอร์ฐานข้อมูลอื่น ฉันรู้ว่าโมดูลอะแดปเตอร์ PostgreSQL จะส่งคืนผลลัพธ์เช่นชุด T2 ของคุณ
kquinn

3
ซ้ำเป็นไปได้ของParse String เพื่อลอยหรือ Int
นาธาน

โปรดสังเกต: เมื่อใช้แผนที่คุณจะได้รับรายการวัตถุแผนที่ในหลาม 3 และ 3.5 สิ่งนี้ทำเพื่อ Python 3.5 ดังกล่าวข้างต้น new_list = list (รายการ (int (a) สำหรับ a in b) สำหรับ b in T1 ถ้า a.isdigit ())
ผู้เข้าพัก

คำถามที่คล้ายกันสำหรับรายการที่ไม่ซ้อนกัน: แปลงสตริงทั้งหมดในรายการเป็น int
Aran-Fey

คำตอบ:


630

int()เป็นฟังก์ชันในตัวของ Python มาตรฐานในการแปลงสตริงเป็นค่าจำนวนเต็ม คุณเรียกมันด้วยสตริงที่มีตัวเลขเป็นอาร์กิวเมนต์และส่งกลับตัวเลขที่แปลงเป็นจำนวนเต็ม:

print (int("1") + 1)

2พิมพ์ดังกล่าวข้างต้น

ถ้าคุณรู้โครงสร้างของรายการของคุณ T1 (มันมีเพียงแค่รายการมีเพียงระดับเดียวเท่านั้น) คุณสามารถทำได้ใน Python 2:

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

ใน Python 3:

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

4
ทำไมไม่T2 = map(lambda lol: map(int, lol), T1)? ไม่ว่าจะเป็นแผนที่หรือรายการความเข้าใจทั้งสองเป็นเรื่องไร้สาระ;)
แกะบิน

4
@flyingsheep แผนที่คู่ดูเหมือนว่าจะโง่สำหรับฉัน
jamylak

วิธีการเกี่ยวกับการลบตัวอย่างของ Python 2 (เพราะการสิ้นสุดของ Python2)
Alisso

28

คุณสามารถทำได้ด้วยรายการความเข้าใจ:

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

ความเข้าใจในรายชื่อภายใน ( [int(column) for column in row]) สร้างlistของints จากลำดับของวัตถุที่น่าเช่นสตริงทศนิยมในint rowความเข้าใจรายการนอก ( [... for row in T1])) T1สร้างรายการของผลลัพธ์ของความเข้าใจในรายชื่อด้านในนำไปใช้กับแต่ละรายการใน

ข้อมูลโค้ดจะล้มเหลวหากแถวใดในนั้นมีวัตถุที่ไม่สามารถแปลงintได้ คุณจะต้องใช้ฟังก์ชันที่ชาญฉลาดกว่าหากคุณต้องการประมวลผลแถวที่มีสตริงที่ไม่ใช่ทศนิยม

หากคุณรู้โครงสร้างของแถวคุณสามารถแทนที่ความเข้าใจในรายการภายในด้วยการเรียกใช้ฟังก์ชันของแถว เช่น.

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

16

ฉันอยากจะใช้รายการความเข้าใจเท่านั้น:

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

12

แทนที่จะใส่int( )วางfloat( )ซึ่งจะช่วยให้คุณใช้ทศนิยมพร้อมกับจำนวนเต็ม


2
คุณช่วยอธิบายรายละเอียดเพิ่มเติมเกี่ยวกับคำตอบของคุณได้ไหม?
Rico

10

ฉันจะเห็นด้วยกับคำตอบทุก ๆ คน แต่ปัญหาคือถ้าคุณไม่มีจำนวนเต็มทั้งหมดพวกเขาจะผิดพลาด

หากคุณต้องการที่จะไม่รวมจำนวนเต็ม

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

นี่ให้ผลเฉพาะตัวเลขจริงเท่านั้น เหตุผลที่ฉันไม่ใช้ความเข้าใจในรายการโดยตรงเป็นเพราะความเข้าใจในรายการรั่วตัวแปรภายในของพวกเขา


2
isdigitหากินลอง-1ใช้ดู int(<str>)เป็นวิธีที่จะตรวจสอบได้โดย/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
ยินดีต้อนรับสู่ Stack Overflow! แทนที่จะโพสต์บล็อกรหัสเท่านั้นโปรดอธิบายว่าเพราะเหตุใดโค้ดนี้จึงแก้ปัญหาที่เกิดขึ้น หากไม่มีคำอธิบายนี่ไม่ใช่คำตอบ
Artemix

7

ลองสิ่งนี้

x = "1"

x เป็นสตริงเนื่องจากมีเครื่องหมายคำพูดล้อมรอบ แต่มีตัวเลขอยู่ในนั้น

x = int(x)

เนื่องจาก x มีหมายเลข 1 อยู่ในนั้นฉันจึงสามารถเปลี่ยนเป็นจำนวนเต็มได้

หากต้องการดูว่าสตริงเป็นตัวเลขหรือไม่คุณสามารถทำได้

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)

ควรพิมพ์เป็น IDLE True เนื่องจาก x เป็นตัวเลข

y_test = is_number(y)

print(y_test)

ควรพิมพ์เป็น IDLE False เนื่องจาก y ไม่ใช่ตัวเลข


2
ฟังก์ชัน is_number ของคุณผิด '1' ไม่เท่ากับ 1 นี่ไม่ใช่ Perl :-P
Veky

3
x.isnumeric()อย่าบูรณาการล้อใช้
bfontaine

4

ใช้รายการความเข้าใจ:

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

1
ใน python 3 จะส่งคืนรายการออบเจกต์แผนที่ :(
CpILL

3

ใน Python 3.5.1 คล้ายกับงานเหล่านี้:

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

และ

Enter number:  4.7
4
5

จอร์จ


3

ดูฟังก์ชั่นนี้

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

แล้วก็

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

คุณสามารถตรวจสอบ

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

evalเป็นความชั่วร้าย: ast.literal_evalคุณควรแทนที่ด้วย
Eli Korvigo

3

อีกโซลูชันที่ใช้งานได้สำหรับ Python 2:

from functools import partial

map(partial(map, int), T1)

Python 3 จะยุ่งเล็กน้อย:

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

เราสามารถแก้ไขได้ด้วย wrapper

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

oldmap(partial(oldmap, int), T1)

1

หากเป็นเพียงสิ่งอันดับหนึ่งสิ่งที่ชอบrows=[map(int, row) for row in rows]จะทำเคล็ดลับได้ (มีรายการความเข้าใจและการเรียกไปยังแผนที่ (f, lst) ซึ่งเท่ากับ [f (a) สำหรับ a ใน lst] ในนั้น)

Eval ไม่ใช่สิ่งที่คุณต้องการในกรณีที่มีบางอย่าง__import__("os").unlink("importantsystemfile")ในฐานข้อมูลของคุณด้วยเหตุผลบางอย่าง ตรวจสอบความถูกต้องของข้อมูลของคุณเสมอ (หากไม่มีสิ่งอื่นใดข้อยกเว้น int () จะเพิ่มขึ้นหากคุณมีข้อมูลที่ไม่ดี)


-1

คุณสามารถทำสิ่งนี้:

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

ฉันต้องการแชร์ตัวเลือกที่มีอยู่ซึ่งยังไม่ได้กล่าวถึงที่นี่:

rumpy.random.permutation(x)

จะสร้างการเรียงสับเปลี่ยนแบบสุ่มของอาร์เรย์ x ไม่ใช่สิ่งที่คุณขออย่างแน่นอนแต่เป็นวิธีแก้ปัญหาสำหรับคำถามที่คล้ายกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.