2015-05-22 12 views
7

Se l'ingresso contiene una riga spazio separato di int, come-Python - memorizzare una stringa e un int usando la mappa (sys.stdin.readline())

1 3 

posso Deposito in un array utilizzando la funzione di map()

arr = map(int,sys.stdin.readline().split()) 

o anche in due variabili distinte, da

n,m = map(int,sys.stdin.readline().split()) 

esiste un modo per utilizzare allo stesso modo per leggere una riga di input che contiene tipi di dati misti. eg.-

foo 3 

dove foo è una stringa e 3 è un numero intero?

+0

i numeri sono sempre positivi? –

+0

È previsto che il primo input sia sempre interpretato come una stringa e il secondo input sia sempre interpretato come un intero? Se è così, ciò cambia il modo in cui l'input dovrebbe essere gestito, e nessuna delle risposte ha davvero a che fare con questo. – user2357112

+0

@PadraicCunningham, no in realtà i numeri possono essere anche negativi, a quanto pare. – Deathstroke

risposta

4

Se avete sempre avuto una stringa e int non negativo:

import sys 
n, m = map(lambda x: (str, int)[x.isdigit()](x) ,sys.stdin.readline().split(None, 1)) 


print(n,m) 

Ma il modo più sicuro è sempre quello di utilizzare un blocco try/tranne quando lancia l'input dell'utente anche quando solo in attesa di un tipo.

come richiesto per il controllo negativo è possibile:

import sys 
n, m = map(lambda x: (str, int)[x.isdigit() or x.strip("-").isdigit()](x) ,sys.stdin.readline().split()) 


print(n, m) 

Ma --10--10-- sarebbe anche superare la prova, ma causa un errore in modo nuovo solo per il vostro caso specifico.

+0

@Deathstroke, sì, ma in realtà solo una soluzione divertente, utilizzando un try/tranne è il modo più sicuro, consentirà anche numeri negativi. –

+0

@PadraicCunningham, ma è necessario verificare la sicurezza se sono sicuro che l'input sarà della forma prevista? Voglio dire, userò questo per risolvere problemi algoritmici sui giudici online. Quindi penso che dovrei optare per qualcosa che è più veloce di qualcosa che è più sicuro? – Deathstroke

+0

@Deathstroke, se è per qualcosa si può essere sicuri che l'input sia sempre in quella forma, allora è sicuro che stia bene. Volevo solo dire in generale che la prova è l'approccio migliore –

4

Per fare ciò dovresti essere in grado di discriminare tra stringhe che possono rappresentare numeri interi e stringhe che non possono. Un esempio è:

def foo(s): 
    try: 
     return int(s) 
    except ValueError: 
     return s 

Quindi è possibile utilizzare normalmente map:

map(foo, sys.stdin.readline().split()) 

La linea di cui sopra per l'ingresso:

abcdef 110 

stamperà:

['abcdef', 110] 
+0

Brillante. Ha funzionato come un fascino. Grazie. :-) – Deathstroke

+0

Molto più pulito di provare a LBYL se il numero è un 'int' valido. – abarnert

1

Puoi fai un quic k "try/except" setup se non stai cercando niente di speciale.

esempio,

def convert(x): 
    try: 
     f = float(x) 
     i = int(f) 
     x = i if i == f else f 
    except: 
     pass 
    return x 

arr = map(convert, sys.stdin.readline().split()) 
+0

Sì! Questo è quello che stavo cercando. – Deathstroke

+0

Ah, sì. Dovrebbe essere risolto ora. – AMacK

+0

Beh, funziona per me. 'abc 123 4.5 6.7' restituisce ['abc', 123, 4.5, 6.7]. Puoi spiegare cosa mi manca? – AMacK

3

Si potrebbe utilizzare str.isdigit per verificare se la stringa può essere fuso ad un numero intero.

>>> inpt = "foo 3" 
>>> [int(s) if s.isdigit() else s for s in inpt.split()] 

Naturalmente, si può fare lo stesso utilizzando map e sys.stdin.readline utilizzando un lambda

>>> map(lambda s: int(s) if s.isdigit() else s, sys.stdin.readline().split()) 
foo 4 
['foo', 4] 

Se si desidera supportare tutti i tipi di tipi di dati, si può provare a literal_eval e ripiegare al stringa di base se non funziona.

import ast 
def try_eval(string): 
    try: 
     return ast.literal_eval(string) 
    except ValueError: 
     return string 

>>> map(try_eval, "42 3.14 foo 'bar' [1,2,3]".split()) 
[42, 3.1400000000000001, 'foo', 'bar', [1, 2, 3]] 
+0

'isdigit' in realtà non verifica se la stringa può essere convertita in un numero intero, quindi non dovresti usarla a tale scopo. – abarnert

+0

@abarnert Sono consapevole che 'isdigit' non gestisce i numeri negativi, ma c'è un caso in cui' isdigit' restituirà 'True' e il cast di' int' fallirà? –

+0

In cima alla mia testa, in versioni ampie di almeno alcune versioni di 2.x, le cifre Unicode non BMP passano 'isdigit' ma vengono respinte da' int'. Nel frattempo, ci sono altre cose che "isdigit' non gestisce oltre ai numeri negativi, come" "+3" 'e" "2" ', e le cifre Unicode non BMP nelle configurazioni strette di 3.0-3.2. Non ho idea se questi siano gli unici casi. Ma questo di per sé è un motivo per non usarlo: "Penso che questi possano essere gli unici problemi da testare" significa solo "non riesco a capire come scrivere la copertura completa del test". Al contrario, 'try' su' int' è garantito per funzionare. – abarnert

2

map è per quando si desidera applicare la stessa trasformazione a ogni elemento dell'input. Questo non si adatta al tuo caso d'uso; vuoi trattare i due input in modi diversi. Dal momento che i dati hanno un formato fisso di corda, quindi intero, che sarebbe stato meglio per analizzare in un modo che produce sempre quel formato:

x, y = raw_input().split() 
y = int(y) 

Se si dispone di più colonne, si potrebbe fare un elenco dei quali funzione da utilizzare per gestire ogni colonna:

handlers = [str, int, int, str, float, int, int] 
a, b, c, d, e, f, g = [f(x) for (f, x) in zip(handlers, raw_input().split())] 

le soluzioni proposte dalle altre risposte non rappresentino formato fisso dell'ingresso. Se l'utente immette

31 42 

x dovrebbero essere "31", non 31, e se l'utente immette

foo bar 

che devono essere rilevati come un errore, anziché assegnare "bar" a y.

+0

In realtà non sembra chiaro dalla domanda se sta chiedendo questa o l'altra risposta ... quindi vale sicuramente la pena sottolineare, se è ciò che effettivamente vuole o no. – abarnert

+1

@abarnert: dal chiarimento nei commenti, sono abbastanza sicuro che questa sia la giusta interpretazione, ma potrei sbagliarmi. – user2357112

+1

@ user2357112 e @abarnet: per chiarimenti, vorrei dire che il formato per l'input che mi aspetto è sempre in 'foo 42' o' foo -42'. L'input non conterrà '32 42' o' foo bar'. È sempre nel formato di 'str int' – Deathstroke

Problemi correlati