Fordert den Benutzer zur Eingabe von 10 Ganzzahlen auf und gibt dann die größte ungerade Zahl aus

107158
Ryan Schreiber

Ich habe einen Python-Code als Antwort auf die folgende Frage geschrieben und muss wissen, ob er auf irgendeine Weise "aufgeräumt" werden kann. Ich bin ein Anfänger-Programmierer und beginne einen Bachelor in Informatik.

Frage: Schreiben Sie einen Code, der den Benutzer auffordert, 10 Ganzzahlen einzugeben, und gibt dann die größte ungerade Zahl aus, die eingegeben wurde. Wenn keine ungerade Zahl eingegeben wurde, sollte eine entsprechende Meldung ausgegeben werden.

Meine Lösung:

a = input('Enter a value: ')
b = input('Enter a value: ')
c = input('Enter a value: ')
d = input('Enter a value: ')
e = input('Enter a value: ')
f = input('Enter a value: ')
g = input('Enter a value: ')
h = input('Enter a value: ')
i = input('Enter a value: ')
j = input('Enter a value: ')

list1 = [a, b, c, d, e, f, g, h, i, j]
list2 = [] # used to sort the ODD values into 
list3 = (a+b+c+d+e+f+g+h+i+j) # used this bc all 10 values could have used     value'3'
                          # and had the total value become an EVEN value

 if (list3 % 2 == 0): # does list 3 mod 2 have no remainder
    if (a % 2 == 0): # and if so then by checking if 'a' has an EVEN value     it rules out
                 # the possibility of all values having an ODD value entered
        print('All declared variables have even values')
    else:
        for odd in list1: # my FOR loop to loop through and pick out the     ODD values
            if (odd % 2 == 1):# if each value tested has a  remainder of one to mod 2
                list2.append(odd) # then append that value into list 2
        odd = str(max(list2)) # created the variable 'odd' for the highest ODD value   from list 2 so i can concatenate it with a string.
        print ('The largest ODD value is ' + odd) 
Antworten
26
Vielen Dank an alle für Ihre Beiträge, das schätze ich sehr! Ich werde einen Blick auf den zusätzlichen Code werfen und versuchen zu verstehen, wie, wo und warum er passt.! Ryan Schreiber vor 7 Jahren 0
Wenn Sie 10 Zeilen haben, die ziemlich genau die gleichen Chancen haben, ist es gut, dass Sie es falsch machen und stattdessen eine Schleife wollen. ThiefMaster vor 7 Jahren 17
tolle Site, tolle Leute! :) Wer sich heutzutage nicht zu einem erfahrenen Programmierer mit all dieser Hilfe entwickeln kann, verdient es, zu sitzen und sich zu fragen, warum er sich nicht vorwärts bewegt. Danke! Ryan Schreiber vor 7 Jahren 1
Sie scheinen ein logisches Problem zu haben, ist Ihre Lösung. Die Eingabe von "2,1,1,2,2,2,2,2,2,2" gibt "Alle deklarierten Variablen haben gerade Werte" zurück. Caramdir vor 7 Jahren 4
AHA. habe das nie gesehen! Ich dachte, ich hätte den logischen Fehler beseitigt ... gutes Auge! Ryan Schreiber vor 7 Jahren 0
@Caramdir: Ich denke, diese Art von Kommentaren sollten Antworten sein. Ich würde es positiv bewerten :) palacsint vor 7 Jahren 0
@palacsint zumindest können wir die Kommentare 0 abstimmen :) Albert Renshaw vor 7 Jahren 1

9 Antworten auf die Frage

31
πόδας ὠκύς

Hier sind ein paar Stellen, an denen Sie Ihren Code präziser gestalten könnten:

Zum einen nehmen die Zeilen 2 bis 11 viel Platz ein, und Sie wiederholen diese Werte erneut, wenn Sie list1 zuweisen. Sie können stattdessen in Betracht ziehen, diese Zeilen in einem Schritt zu kombinieren. Ein Listenverständnis ermöglicht es Ihnen möglicherweise, diese beiden Aktionen in einem Schritt auszuführen:

>>> def my_solution():
    numbers = [input('Enter a value: ') for i in range(10)]

Ein zweites Listenverständnis kann Ihre Ergebnisse weiter einschränken, indem Sie gerade Werte entfernen:

    odds = [y for y in numbers if y % 2 != 0]

Sie könnten dann sehen, ob Ihre Liste Werte enthält. Wenn nicht, waren keine ungeraden Werte in Ihrer Liste. Ansonsten könnten Sie das Maximum der Werte finden, die in Ihrer Liste verbleiben, die alle ungerade sein sollten:

    if odds:
        return max(odds)
    else:
        return 'All declared variables have even values.'

Insgesamt können Sie also Folgendes als Ausgangspunkt für die Verfeinerung Ihres Codes verwenden:

>>> def my_solution():
        numbers = [input('Enter a value: ') for i in range(10)]
        odds = [y for y in numbers if y % 2 != 0]
        if odds:
            return max(odds)
        else:
            return 'All declared variables have even values.'


>>> my_solution()
Enter a value: 10
Enter a value: 101
Enter a value: 48
Enter a value: 589
Enter a value: 96
Enter a value: 74
Enter a value: 945
Enter a value: 6
Enter a value: 3
Enter a value: 96
945
Gute Antwort, aber "wenn len (list2)! = []:" Ist nicht wirklich pythonisch. Sie könnten einfach folgendes tun: `wenn len (list2):` Zenon vor 7 Jahren 2
Willkommen bei Code Review und vielen Dank für die hervorragende Antwort. Adam vor 7 Jahren 1
Vielen Dank für Ihr Wissen und Ihre Verbesserungen. Ich habe die Antwort aktualisiert. πόδας ὠκύς vor 7 Jahren 0
@Zenon konnte nicht einfach `wenn list2:`? Snakes and Coffee vor 7 Jahren 8
@SnakesandCoffee ja könnte und sollte, weil es viel besser ist. orlp vor 7 Jahren 1
@ user1775603 Eine Mikrooptimierung zum Testen, ob eine Zahl ungerade ist, lautet y & 1 == 1 Ifthikhan vor 7 Jahren 0
Zur weiteren Optimierung könnten Generatoren und Trys Listen und Bedingungen ersetzen: `n = (Eingabe ('Enter ..') für i in xrange (10))` und `o = (y für y in n, wenn n% 2)` . `try: return max (o)` `außer ValueError: 'All deklariert ...'` zurückgeben ejrb vor 6 Jahren 0
Diese Übersicht zeigt die oben genannten Änderungen. https://gist.github.com/ejrb/7581712 ejrb vor 6 Jahren 0
13

Ein Tipp: Prüfen Sie sofort nach jeder einzelnen Frage. Es ist keine Liste zum Speichern von Werten erforderlich, da Sie jede gerade Zahl sofort vergessen können und nur der größten ungeraden Zahl folgen können.

Und: es gibt listobject.append () BTW, siehe http://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range

Ein wunderbarer Tipp: Vergessen Sie, was Sie für das anstehende Problem nicht wissen müssen. Behalten Sie einfach die größte ungerade Anzahl oder einen Indikator, den Sie noch nicht haben (wie die größte bei Null beginnen und am Ende auf Null prüfen). Ross Millikan vor 7 Jahren 1
12
andrew cooke

Niemand hat mir den Code gegeben, den ich schreiben würde. Er erstellt keine Liste, sondern verfolgt die Antwort in einer Schleife. Die Logik ist etwas komplexer, vermeidet jedoch das Speichern von Werten (hier spielt es keine Rolle, da es nur 10 Werte sind, aber ein ähnliches Problem bei der Eingabe aus einem anderen Programm, möglicherweise mehr Daten als Speicherplatz).

maxOdd = None
for _ in range(10):
    value = int(input('Enter a value: '))
    if (value % 2 and (maxOdd is None or value > maxOdd)):
        maxOdd = value
if maxOdd:
    print('The largest odd value entered was', maxOdd)
else:
    print('No odd values were entered.')

Beachten Sie, dass ich nicht-Null-Werte als behandele True, also value % 2ein Test für die Ungerade (da dies einen Restwert ungleich Null ergibt und Python nicht-Null-Werte als behandelt true). In ähnlicher Weise if maxOddprüft das maxOddnicht None(auch nicht Null, aber es kann nicht Null sein, weil es gerade ist).

Ein anderer Weg, der näher an den anderen Antworten liegt, indem er die Zahlen als eine Folge behandelt, jedoch nicht alles im Speicher speichert, ist die Verwendung eines Generators:

from itertools import islice

def numbers():
    while True:
        yield input('Enter a value: ')

def odd(n):
    return n % 2

try:
    print('The largest odd value entered was',
          max(filter(odd, map(int, islice(numbers(), 10)))))
except ValueError:
    print('No odd values were entered.')

Dies ist eher "fortgeschritten", numbers()erstellt jedoch einen Generator, und die Funktionskette max, filter, map, isliceruft dies effektiv für jeden Wert auf (etwas vereinfacht). Das Endergebnis ist also eine Art Pipeline, die wiederum verhindert, dass alles im Speicher bleibt.

(Das ValueErrorpassiert, wenn maxkeine Werte empfangen werden.)

Eine andere Schreibweise wäre (beachten Sie das Fehlen eckiger Klammern):

try:
    print('The largest odd value entered was',
          max(filter(odd,
                     map(int, (input('Enter a value: ')
                               for _ in range(10))))))
except ValueError:
    print('No odd values were entered.')

Wo (input ...)ist ein Generator-Ausdruck.

danke, ur richtig, es ist für mich im Moment etwas fortgeschritten, obwohl mir die Idee gefällt, die Werte nicht zu speichern. irgendwelche Vorschläge für ein gutes Lesematerial in Bezug auf Computerlogik? Ryan Schreiber vor 7 Jahren 0
6
Fivesheep

ein Ratschlag:

  • Sie benötigen keine 10 benannten Variablen für die Eingabe, verwenden stattdessen ein Array und eine Schleife, um dies zu tun
  • Listenverständnis verwenden, um alle ungeraden Zahlen herauszufiltern
  • Schauen Sie sich die String-Formatierungsdokumente von Python an
Fivesheep, vielen Dank für die Beantwortung von Fragen zur Code Review. Ich hoffe du genießt es. :) Deine Antwort ist bereits sehr nützlich, da Ryan es bemerkt hat, aber ich denke, es könnte ein bisschen mehr Details gebrauchen: z. Welche String-Formatierungsfunktionen empfehlen Sie? Kann gezeigt werden, wie das Listenverständnis aussehen würde? Quentin Pradet vor 7 Jahren 2
Können Sie mir erklären, wie Sie die Variablen definieren, ohne sie alle eingeben zu müssen? Ist es nur a = 0, b = 0 usw.? Verwenden Sie eine FOR-Schleife. Um die Fragen zu durchlaufen, habe ich versucht, die oben genannten Variablen zu verwenden und benutzte eine FOR-Schleife, und die Fragen wurden durchlaufen, aber meine Ausgabe war total falsch: 8 Ryan Schreiber vor 7 Jahren 1
@Ryan Sie müssen die Variablen nicht per se definieren. Sie müssen lediglich eine Liste mit 10 Eingaben erstellen. Mit anderen Worten, Sie möchten so etwas wie: [Eingabe ('Geben Sie einen Wert ein:') für i im Bereich (0,10)]. Dieses Listenverständnis wird in eine Liste von 10 Werten umgewandelt, ohne dass 10 separate Variablen definiert werden müssen. πόδας ὠκύς vor 7 Jahren 0
@ user1775603, ja, danke, jetzt fange ich an, mir dessen bewusst zu werden. Es ist WAAYY einfacher, das zu tun. Es ist sehr cool. Ryan Schreiber vor 7 Jahren 0
3
paramburu

Ich würde es so machen:

def is_odd(x):
    return x & 1 and True or False


olist = []

for i in xrange(10):
    while True:
        try:
            n = int(raw_input('Enter a value: '))
            break
        except ValueError:
            print('It must be an integer.')
            continue

    if is_odd(n):
        olist.append(n)

try:
    print 'The largest ODD value is %d' % max(olist)
except ValueError:
    print 'No ODD values were entered'

Die is_oddFunktion prüft das letzte Bit der Ganzzahl, um zu sehen, ob es gesetzt ist (1) oder nicht (0). Wenn es eingestellt ist, muss es ungerade sein. ZB: 010 (2 ist nicht ungerade) 011 (3 ist ungerade).

Außerdem würde ich die Quoten schnell filtern, sodass ich die Liste nicht mehrmals analysieren muss und xrange (einen Generator) verwenden würde, um den Speicher "sicher" zu halten.

Für diesen Fall wären diese "Optimierungen" nicht notwendig, da die Liste nur Größe 10 hat und nicht viel berechnet wird. Wenn Sie jedoch viele Ganzzahlen nehmen müssten, müssten Sie dies berücksichtigen.

Bei python3 bevorzuge ich den Bereich, da er für eine langsame Bewertung optimiert ist. xrange .. fühlt sich beim Lesen nicht gut an. : P Mahesh vor 7 Jahren 0
3
gerrit

Da Sie nicht angegeben haben, ob Sie Python 2 oder Python 3 verwenden, bin ich nicht sicher, ob die unten stehende Antwort relevant ist. In Python 2 inputist es riskant. In Python 3 inputgeht das gut.

Obwohl einige Antworten durch ersetzt input(...)wurden int(raw_input(...)), glaube ich nicht, dass jemand bisher erklärt hat, warum dies empfohlen wird.

input in Python 2.x als schädlich eingestuft

In Python 2.x input(x)ist äquivalent zu eval(raw_input(x)). Siehe zum Beispiel in der Dokumentation inputin Python 2.7 und in der Dokumentationraw_input . Dies bedeutet, dass ein Benutzer einen beliebigen Python-Ausdruck ausführen kann, z.

>>> input("Number? ")
Number? os.unlink("/path/to/file") 

Verwenden Sieraw_inputinput daher in Python 2 immer eher als .

Einige Erklärung: raw_inputGibt eine Zeichenfolge zurück, zum Beispiel '10'. Diese Zeichenfolge müssen Sie in eine Zahl konvertieren. Die Funktion intkann dies für Sie tun ( siehe Dokumentation in Python 2.7 ). Wo immer Sie also inputeine ganze Zahl erhalten, möchten Sie lieber int(raw_input(...)). Dadurch wird die Eingabe als String übernommen und sofort in eine Ganzzahl umgewandelt. Dies führt zu einer Ausnahme, wenn die Eingabe nicht in eine Ganzzahl konvertiert werden kann:

>>> int(raw_input("Number? "))
Number? os.unlink("/path/to/file")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'os.unlink("/path/to/file")'

In Python 3 inputentspricht Python 2 raw_input, siehe beispielsweise die Dokumentation zu inputin Python 3.3 .

Aha. Ich habe versucht, dieses Programm zu erstellen, und es würde nicht laufen, wenn ich raw_input verwendete. Ich benutze Python2.7, aber es brauchte Eingabe und funktionierte. warum sollte das sein? und vielen Dank für die Einsicht Ryan Schreiber vor 7 Jahren 0
@ RyanSchreiber Ich habe ein paar Erklärungen hinzugefügt gerrit vor 7 Jahren 0
fantastisch, okay, ich verstehe jetzt, warum es nie funktioniert hat! Noch ein Hinweis dazu, warum sollte ich als Programmierer den Text als Zeichenfolge eingeben und in eine Ganzzahl konvertieren lassen? Ist dies eine sichere Art der Programmierung und wenn ja, was ist der Grund dafür? und übrigens, ja, ich werde die Dokumentation lesen, ich würde gerne eine andere Ansicht von außen darauf haben :) Ryan Schreiber vor 7 Jahren 0
Sicherlich meinen Sie "raw_input" und nicht "input" Janus Troelsen vor 7 Jahren 0
@Ysangkok Oops, ja mache ich natürlich, jetzt behoben. gerrit vor 7 Jahren 0
2
archery1234

This is the finger exercise from Ch.2 of Introduction to Computation and Programming Using Python by John V. Guttag. It's the recommended text for the MITx: 6.00x Introduction to Computer Science and Programming. The book is written to be used with Python 2.7.

At this point the book has only introduced variable assignment, conditional branching programs and while loops as well as the print function. I know as I'm working through it. To that end this is the code I wrote:

counter = 10
while counter > 0:
    x = int(raw_input('Please type in integer: '))
    if counter == 10 or (x%2 and x > ans):
        ans = x
    if ans%2 == 0: # Even Number Safeguard
        ans = x 
    counter = counter -1
if ans%2 != 0:
    print 'The largest odd number entered was', str(ans)
else:
    print 'No odd number was entered'`

Seems to work. It can probably be shortened but the idea was to use only the limited concepts that have been covered in the book.

EDITED to include commments to shorten code. Still meets the criteria of using the limited concepts introduced in the book.

Ich bezog mich auf die genaue Frage aus dem Text. Ich habe es jetzt geändert. archery1234 vor 7 Jahren 0
Oh ok. Es schien auf den ersten Blick eine neue Frage zu sein. Jamal vor 7 Jahren 0
`ans = ans` tut nichts, und Sie könnten alle Bedingungen von 'if ... else ... elif' auf einen einzigen vereinfachen:` if counter == 10 oder (x% 2 und x> ans): ans = x` Stuart vor 7 Jahren 1
Ja, es kann definitiv gekürzt werden. Irgendwann werde ich mich mit der rechnerischen Denkweise auseinandersetzen. archery1234 vor 7 Jahren 0
Ich schlage vor: `ans = None` oben,` if x% 2 und (ans ist None oder x> ans) `innerhalb der Schleife und` if ans ist keine 'nach der Schleife. Wenn Sie "10" und "% 2" nicht wiederholen, wird der Code leichter gewartet. (Das ist am Ende @ andrewcookes Antwort, außer ohne `range ()`.) 200_success vor 7 Jahren 0
0
Albert Renshaw

Warum nicht jeden Wert mit seinem niedrigstwertigen Bit (auch als Zahl in Modulo 2 bezeichnet) multiplizieren, so dass gerade Zahlen Null sind und ungerade Zahlen bleiben, wie sie sind, und dann max()die größte Zahl zurückgeben (die ungerade sein muss, da alle Zahlenwerte) Abend wurden mit Null multipliziert)

** Beachten Sie, vorausgesetzt, es gibt keine negativen Zahlen, wenn es nur max gibt, aber alle "0" von Ihrem Array entfernen.

Modulo 2 bildet alles auf 0 oder 1 ab, was nicht nützlich ist. 200_success vor 7 Jahren 0
@ 200_success Wenn Sie die vollständige Antwort lesen, würden Sie sehen, dass ich MULTIPLY die Zahl in Modulo 2 selbst sagte ... was alle geraden Zahlen zu 0 machen würde und alle ungeraden Zahlen so bleiben würden, wie sie waren (da sie mit 1 multipliziert wurden). DANN benutze max () und gib die größte Zahl zurück (die per Definition die größte ODD-Zahl wäre). Albert Renshaw vor 7 Jahren 0
@ 200_success Wenn Sie Ihre Ablehnung rückgängig machen könnten, würden wir uns sehr freuen. Albert Renshaw vor 7 Jahren 0
Ich habe den Wortlaut der Klarheit halber geändert und meine Stimme umgekehrt. 200_success vor 7 Jahren 0
@ 200_success Vielen Dank :) Es bedeutet viel für mich, haha! Albert Renshaw vor 7 Jahren 0
0
Russ

I think in this case, performance is of no concern and so the priority is making workings of the program as immediately obvious as possible.

user_input = [input('Enter a value: ') for x in range(10)]
numbers = map(int, user_input)
odd_numbers = [n for n in numbers if n % 2 != 0]
if odd_numbers:
    print(max(odd_numbers))
else:
    print("All the numbers are even")

Here each line is a new logical and concise step.

  1. Get numbers from user as strings using input in Python 3 or raw_input in Python 2.
  2. Convert the strings to ints.
  3. Extract all the odd numbers from the list of numbers.
  4. Print the biggest odd number or a message.