Jak przekonwertować ciągi na liczby całkowite w Pythonie?

438

Mam krotkę z zapytania MySQL, takiego jak to:

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

Chciałbym przekonwertować wszystkie ciągi znaków na liczby całkowite i umieścić je z powrotem na liście list:

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

Próbowałem to osiągnąć, evalale nie uzyskałem jeszcze żadnego przyzwoitego rezultatu.

elfuego1
źródło
2
Może warto rozważyć inny moduł adaptera bazy danych? Wiem, że moduły adaptera PostgreSQL zwrócą wyniki takie jak Twój zestaw T2.
kquinn
3
Możliwy duplikat Parse String do Float lub Int
Nathan
zauważ: podczas korzystania z mapy otrzymasz listę obiektów mapy w python 3 i 3.5. Robi to dla Pythona 3.5, jak wspomniano powyżej. nowa_lista = lista (lista (int (a) dla a w b) dla b w T1, jeśli a.isdigit ())
Gość
Podobne pytanie do listy nie zagnieżdżonej: Konwertuj wszystkie ciągi z listy na int
Aran-Fey

Odpowiedzi:

630

int()jest standardową wbudowaną funkcją Pythona do konwersji ciągu na wartość całkowitą. Wywołujesz go ciągiem zawierającym liczbę jako argument, a on zwraca liczbę przekonwertowaną na liczbę całkowitą:

print (int("1") + 1)

Powyższe wydruki 2.

Jeśli znasz strukturę swojej listy, T1 (że zawiera ona tylko listy, tylko jeden poziom), możesz to zrobić w Python 2:

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

W Pythonie 3:

T2 = [list(map(int, x)) for x in T1]
rozwijać
źródło
4
dlaczego nie T2 = map(lambda lol: map(int, lol), T1)? Albo mapa, albo lista, oba są głupie;)
latające owce
4
@flyingsheep Podwójna mapa wydaje mi się głupia, wydaje się w porządku.
jamylak
Co powiesz na usunięcie przykładu Python 2 (z powodu końca życia Python2)?
Alisso,
28

Możesz to zrobić ze zrozumieniem listy:

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

Wewnętrzna listowego ( [int(column) for column in row]) buduje listz ints z sekwencji int-able obiektów, takich jak ciągi znaków po przecinku, w row. Zewnętrzne rozumienie listy ( [... for row in T1])) buduje listę wyników wewnętrznego rozumienia listy zastosowanego do każdego elementu w T1.

Fragment kodu nie powiedzie się, jeśli którykolwiek z wierszy zawiera obiekty, których nie można przekonwertować int. Będziesz potrzebować inteligentniejszej funkcji, jeśli chcesz przetwarzać wiersze zawierające ciągi nie dziesiętne.

Jeśli znasz strukturę wierszy, możesz zastąpić rozumienie wewnętrznej listy wywołaniem funkcji wiersza. Na przykład.

T2 = [parse_a_row_of_T1(row) for row in T1]
Will Harris
źródło
16

Wolałbym używać tylko list ze zrozumieniem:

[[int(y) for y in x] for x in T1]
odwl
źródło
12

Zamiast int( )put, put, float( )które pozwoli ci używać miejsc po przecinku wraz z liczbami całkowitymi.

weir99
źródło
2
Czy możesz wyjaśnić więcej szczegółów na temat swojej odpowiedzi?
Rico
10

Zgadzam się z dotychczasowymi odpowiedziami wszystkich, ale problem polega na tym, że jeśli nie masz wszystkich liczb całkowitych, ulegną one awarii.

Jeśli chcesz wykluczyć liczby całkowite, to

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

Daje to tylko rzeczywiste cyfry. Powodem, dla którego nie używam bezpośredniego rozumienia listy, jest to, że rozumienie listy przecieka ich wewnętrzne zmienne.

Christian Witts
źródło
2
isdigitjest trudne, spróbuj -1. int(<str>)jest sposobem sprawdzenia przez 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
źródło
7
Witamy w Stack Overflow! Zamiast pisać tylko blok kodu, wyjaśnij, dlaczego ten kod rozwiązuje postawiony problem. Bez wyjaśnienia nie jest to odpowiedź.
Artemix,
7

Spróbuj tego.

x = "1"

x jest łańcuchem, ponieważ zawiera cudzysłowy, ale ma w sobie liczbę.

x = int(x)

Ponieważ x ma w sobie cyfrę 1, mogę go zamienić na liczbę całkowitą.

Aby sprawdzić, czy ciąg znaków jest liczbą, możesz to zrobić.

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)

Powinien zostać wypisany na IDLE True, ponieważ x jest liczbą.

y_test = is_number(y)

print(y_test)

Powinien być drukowany na IDLE False, ponieważ y nie jest liczbą.

TheRedstoneLemon
źródło
2
Twoja funkcja is_number jest niepoprawna. „1” nie jest równe 1. To nie jest Perl. :-P
Veky
3
Nie wymyślaj koła ponownie, użyj x.isnumeric().
bfontaine
4

Korzystanie ze zrozumień listy:

t2 = [map(int, list(l)) for l in t1]
Jon
źródło
1
w python 3 zwraca listę obiektów na mapie :(
CpILL 15.04.16
3

W Pythonie 3.5.1 takie rzeczy działają:

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

i

Enter number:  4.7
4
5

Jerzy.

George Moraitis
źródło
3

Zobacz tę funkcję

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

Następnie

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

Możesz także sprawdzić

if val == None:  # True if input value can not be converted
    pass  # Note: Don't use 'if not val:'
Shameem
źródło
evaljest złe: powinieneś je zastąpić ast.literal_eval.
Eli Korvigo,
3

Kolejne funkcjonalne rozwiązanie dla Python 2:

from functools import partial

map(partial(map, int), T1)

Python 3 będzie jednak nieco niechlujny:

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

możemy to naprawić za pomocą opakowania

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

oldmap(partial(oldmap, int), T1)
Eli Korvigo
źródło
1

Jeśli to tylko krotka krotek, coś takiego rows=[map(int, row) for row in rows]wystarczy. (Jest tam zrozumienie listy i wywołanie map (f, lst), które jest równe [f (a) dla in lst], tam.)

Ewaluacja nie jest tym, co chcesz zrobić, na wypadek gdyby __import__("os").unlink("importantsystemfile")z jakiegoś powodu w bazie danych było coś takiego . Zawsze sprawdzaj poprawność danych wejściowych (jeśli nie ma nic innego, wyjątek int () pojawi się, jeśli masz złe dane wejściowe).

AKX
źródło
-1

Możesz zrobić coś takiego:

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
źródło
-1

Chcę udostępnić dostępną opcję, o której jeszcze nie wspomniano tutaj:

rumpy.random.permutation(x)

Wygeneruje losową permutację tablicy x. Nie do końca to, o co prosiłeś, ale jest to potencjalne rozwiązanie podobnych pytań.

samvoit4
źródło