7
votes

Python - Stockez une chaîne et un INT à l'aide de la carte (sys.stdin.readline ())

Si l'entrée contient une ligne d'intension séparée d'int, similaire- xxx

i peut cartographier le stocker dans un tableau à l'aide de la carte " Fonction xxx

ou même dans deux variables distinctes, par xxx

existe-t-il un moyen d'utiliser de la même manière pour lire une ligne d'entrée qui contient des types de données mixtes. par exemple .- xxx

foo est une chaîne et 3 est un entier? >


5 commentaires

Les numéros sont-ils toujours positifs?


Est-il prévu que la première entrée est toujours interprétée comme une chaîne et la deuxième entrée est toujours interprétée comme un entier? Si tel est le cas, cela change comment l'entrée doit être traitée et aucune des réponses ne traite vraiment de cela.


@PadraicCunningham, pas en fait, les chiffres peuvent également être négatifs, apparemment.


@ user2357112 Oui, il est toujours prévu que la première entrée sera une chaîne et la seconde en tant qu'oquet (positif ou négatif). Comment cela change-t-il comment l'entrée doit être manipulée?


@Deathstroke: J'ai posté une réponse décrivant comment le gérer.


5 Réponses :


4
votes

Pour faire cela, vous devriez être capable de discriminer entre les chaînes pouvant représenter des entiers et des chaînes qui ne peuvent pas. Un exemple est le suivant: xxx

alors vous pouvez normalement utiliser mapper : xxx

la ligne ci-dessus pour l'entrée: xxx

imprimera: xxx


2 commentaires

Brillant. Travaillé comme un charme. Merci. :-)


Beaucoup plus propre que d'essayer de lbyl si le numéro est un index valide .



1
votes

Vous pouvez faire un "essai / sauf" rapide si vous ne cherchez rien de fantaisie.

E.g., P>

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


4 commentaires

Oui! C'est ce que je cherchais.


Ah oui. Il devrait être corrigé maintenant.


Eh bien ça marche pour moi. 'ABC 123 4.5 6.7' Retourne ['ABC', 123, 4.5, 6.7]. Pouvez-vous expliquer ce qui me manque?


@Amack: Pas ce que vous avez demandé à l'origine, mais ... la conversion vers INT par flotteur n'est pas toujours la même que la conversion vers l'INT directement, ni une bonne idée. Essayez-le avec '10000000000000000000000' et vous obtiendrez [99999999999999991611392] .



3
votes

Vous pouvez utiliser str.isdigit code> Pour tester si la chaîne peut être couplée sur un numéro entier. xxx pré>

Bien sûr, vous pouvez faire la même chose à l'aide de la carte code> et sys. stdin.readline code> à l'aide d'un lambda code> p> xxx pré>

Si vous souhaitez prendre en charge toutes sortes de types de données, vous pouvez essayer de littéral_eval code>

et retombez à la chaîne de base si Cela ne fonctionne pas. P>
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]]


3 commentaires

isdigit ne teste pas réellement si la chaîne peut être mise à couler sur un numéro entier, de sorte que vous ne devriez donc pas l'utiliser à cet effet.


@Abarnert Je suis conscient que isdigit ne gère pas les nombres négatifs, mais existe-t-il un cas où isdigit retournera true et casting sur int échouera?


En haut de ma tête, dans de larges générations d'au moins certaines versions de 2.x, non-BMP Unicode Digits Pass isdigit mais sont rejetés par int . Pendant ce temps, il existe d'autres choses isdigit ne manipulent pas outre les nombres négatifs, tels que "+ 3" et "2" et non-BMP Chiffres Unicode dans des constructions étroites de 3.0-3.2. Je ne sais pas si ce sont les seuls cas. Mais cela est en soi une raison de ne pas l'utiliser: "Je pense que celles-ci peuvent être les seuls problèmes à tester", signifie simplement "que je ne peux pas comprendre comment écrire une couverture de test complète". En revanche, essayer autour de int est garanti de fonctionner.



4
votes

Si vous aviez toujours une chaîne et non négative INT:

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


print(n, m)


12 commentaires

@Deathstroke, Yep mais vraiment juste une solution amusante, à l'aide d'un essai / sauf est le moyen le plus sûr, il permettra également de chiffrer les nombres négatifs.


@Padraiccunningham, mais dois-je vérifier pour la sécurité si je sache, à coup sûr que l'entrée sera de la forme attendue? Je veux dire, je vais l'utiliser pour résoudre des problèmes algorithmiques sur les juges en ligne. Donc, je suppose que je devrais aller pour quelque chose qui est plus rapide plus que quelque chose qui est plus sûr?


@Deathstroke, si c'est pour quelque chose, vous pouvez être sûr de l'entrée étant toujours sous ce formulaire, alors c'est bien sûr. Je veux juste dire en général un essai est la meilleure approche


Je vois. Juste hors de curiosité, existe-t-il un moyen d'autoriser également des entiers négatifs à l'aide de la fonction Lambda?


Très bonne réponse. Puisque vous décompressez dans n, m , vous voudrez peut-être éliminer la possibilité d'une ValueError en limitant la scission à 1. IE, divisé (aucun, 1)


Même la manipulation des nombres négatifs n'est toujours pas vraiment correcte. 0123 est tous des chiffres, mais pas un argument valide sur int (3.x) ou interprété comme octal (2.x). Certains chiffres Unicode sont valables dans un Python Int, et certains ne sont pas. 0x12ab est un Python valide Int, mais ce n'est pas tous des chiffres. Essayer d'écrire une fonction qui prédit tout ce qui compte en tant que représentation valide int avant appelant int est très difficile. Si vous souhaitez n'importe quel Python int , appelez simplement int avec essayez . Si vous voulez quelque chose de différent, définissez exactement ce que vous voulez, puis mettez en œuvre cela.


@Abarnert, oui, comme je l'ai dit plus d'une fois dans ma réponse, c'est en général un essai / sauf si la voie à suivre est la solution, la réponse est spécifique au besoin de l'OP qui est destinée aux sites de problèmes de code en ligne.


Je ne vois pas comment "les sites de problèmes de code en ligne" fait une différence ici. Il dit "plus vite que quelque chose qui est plus sûr", mais cela n'est clairement pas algorithmiquement plus rapide ou plus lent, juste une petite constante-plus, une vérification compliquée de lbyl est probablement plus lente que d'essayer / sauf de toute façon. De plus, ne sont pas des problèmes en ligne exactement le type d'endroit où vous devriez vous attendre à voir des "intrants astuces" rares qui vont briser le code naïf?


@Abarnert, pas vraiment en fait, la multitude de problèmes que j'ai faits a un format d'entrée strict, il serait difficile de traiter des lignes d'entrée si elles étaient aléatoires. Le format d'entrée est littéralement défini sur la plupart des sites. Et encore une fois cette réponse est juste pour s'amuser et tout ce qui est dans la vie doit être sérieux. La question était plutôt allusion à un doubleur à faire ce que l'OP faisait déjà, ce que j'ai fourni avec une recommandation visant à utiliser un essai / sauf généralement.


Je ne m'attendrais pas à ce qu'ils soient aléatoire , je m'attendrais à ce qu'ils soient choisis avec soin par les personnes qui écrivent les tests. Par exemple, je sais que la codité (qui est plus utilisée pour le dépistage des entretiens que pour les problèmes de type concours) a souvent des questions qui testent explicitement pour de mauvaises hypothèses telles que la suppression de "nombre" dans le problème signifie "entier positif" quand il n'y a aucune raison d'assumer cette.


Quoi qu'il en soit, je ne suggère pas que votre réponse soit mauvaise, commentant simplement que l'OP ne devrait pas rechercher «Comment puis-je en faire cela encore plus compliqué pour éviter d'utiliser Essayer / Sauf pour des raisons de performance», car cela ne contribue probablement pas à la performance , la performance n'est probablement pas pertinente et il n'est toujours pas assez compliqué d'être correct.


@abarnert, la curiosité est la mère de la découverte.



2
votes

mappe est pour quand vous souhaitez appliquer la même transformation à chaque élément de l'entrée. Cela ne correspond pas à votre cas d'utilisation; Vous voulez traiter les deux entrées de différentes manières. Étant donné que les données ont un format fixe de chaîne, alors entier, il serait préférable de l'analyser de manière à produire ce format: xxx

Si vous avez plus de colonnes, vous pourriez faire Une liste de laquelle fonction à utiliser pour gérer chaque colonne: xxx

Les solutions suggérées par les autres réponses ne tiennent pas compte du format fixe de l'entrée. Si l'utilisateur entrait xxx

x doit être "31" , pas 31 , et si l'utilisateur entrait xxx

qui doit être détecté comme une erreur plutôt que d'attribuer "bar" à y y .


3 commentaires

Il ne semble pas évidemment clairement la question de savoir s'il demande cela ou l'autre réponse ... Donc, il vaut vraiment la peine d'être souligné, que ce soit ce qu'il veut vraiment ou non.


@Abarnert: De la clarification des commentaires, je suis sûr que c'est la bonne interprétation, mais je pourrais me tromper.


@ user2357112 et @Abarnet: Pour clarification, j'aimerais indiquer que le format de l'entrée que je m'attends est toujours sous la forme de FOO 42 ou FOO -42 . L'entrée ne contiendra pas 32 42 ou foo bar . Il est toujours au format de str int