我已经写了一段python代码来回答以下问题,我想知道是否可以通过任何方式对其进行“整理”。我是一名初学者程序员,并且正在获得计算机科学学士学位。


问题:编写一段代码,要求用户输入10个整数,然后输出最大的奇数。已输入。如果未输入奇数,则应打印出一条信息。


我的解决方案:

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) 


评论

谢谢大家的投入,我非常感谢!我将看一下额外的代码,并尝试了解它的方式,位置和原因。!

如果您有10行,几乎相同的机会就是您做错了,而是想要循环。

很棒的网站很棒的人! :)那些无法在所有这些帮助下成为熟练程序员的人都应该坐下来,想知道为什么他们不前进。.谢谢!

您似乎有一个逻辑问题是您的解决方案。输入2,1,1,2,2,2,2,2,2,2返回所有声明的变量都具有偶数值。

@palacsint至少我们可以投票给评论0 :)

#1 楼

您可以在以下几个地方使代码更简洁:

首先,第2-11行占用大量空间,在分配list1时,您在下面再次重复这些值。相反,您可以考虑尝试将这些行合并为一个步骤。列表理解可以让您一步执行两个操作:

>>> 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.'


评论


\ $ \ begingroup \ $
很好的答案,但是如果len(list2)!= []:不是真正的pythonic。您可以简单地做:如果len(list2):
\ $ \ endgroup \ $
–氙气
13年2月16日在21:35

\ $ \ begingroup \ $
欢迎来到代码审查,并感谢您的出色回答。
\ $ \ endgroup \ $
–亚当
13年2月16日在22:18



\ $ \ begingroup \ $
感谢你们双方分享您的知识和改进。我更新了答案。
\ $ \ endgroup \ $
–πόδαςὠκύς
13年2月16日在22:34

\ $ \ begingroup \ $
@Zenon,如果list2:您不能做吗?
\ $ \ endgroup \ $
–蛇和咖啡
13年2月16日在23:37

\ $ \ begingroup \ $
@SnakesandCoffee是的,您可以而且应该这样做,因为它要好得多。
\ $ \ endgroup \ $
–orlp
13年2月17日在8:08



#2 楼

没有人提供我要编写的代码,该代码不会创建列表,而是在循环中跟踪答案。逻辑稍微复杂一点,但是它避免存储值(这里并不重要,因为它只有10个值,但是来自另一个程序的输入类似的问题,可能有更多的数据超出了内存的容量)。 />
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.')


请注意,我将非零值视为True,因此value % 2是对奇数的检验(因为它提供了非零余数,而Python处理了非零值)值如true)。类似地,if maxOdd测试maxOdd不是None(也不为零,但不能为零,因为那是偶数)。

另一种方式,更接近其他答案,因为它将数字视为顺序,但仍避免将所有内容存储在内存中,是使用生成器:

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.')


这是“更高级的”,但是numbers()创建了一个生成器,并且链函数max, filter, map, islice有效地为每个值调用该函数(略微简化)。因此,最终结果是一种避免再次将所有内容保留在内存中的管道。

ValueErrormax没有收到任何值时发生。)

另一个(注意没有方括号):

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.')


其中(input ...)是生成器表达式。

评论


\ $ \ begingroup \ $
谢谢你,对,这对我来说有点先进,尽管我喜欢不存储值的想法。对与计算机逻辑相关的良好阅读材料有何建议?
\ $ \ endgroup \ $
– Ryan Schreiber
13年2月17日在6:50

#3 楼

提示:问完每个问题后,请立即检查。不需要存储值的列表,因为您可以立即忘记每个偶数,而只跟随最大的奇数。

并且:有listobject.append()BTW,请参见http:// docs .python.org / 3 / library / stdtypes.html#sequence-types-list-tuple-range

评论


\ $ \ begingroup \ $
一个绝妙的技巧:忘记手头问题所不需要的知识。只需保持到目前为止最大的奇数或没有指标(例如,将最大的奇数从零开始,然后测试零)即可。
\ $ \ endgroup \ $
–罗斯·米利坎(Ross Millikan)
13年2月20日在5:31

#4 楼

一些建议:


您不需要10个命名变量作为输入,而是使用数组和循环来实现
使用列表推导过滤掉所有奇数数字
看一下python的字符串格式文档


评论


\ $ \ begingroup \ $
Fivesheep,感谢您回答有关代码审查的问题。我希望你喜欢它。 :)正如Ryan指出的那样,您的答案已经非常有用,但是我认为它可以使用更多详细信息:您推荐什么字符串格式化功能?有可能显示列表理解的样子吗?
\ $ \ endgroup \ $
– Quentin Pradet
13年2月16日在20:12



\ $ \ begingroup \ $
您能给我解释一下如何定义变量而不必全部输入吗,仅仅是a = 0,b = 0等等。我是否使用FOR循环遍历问题,我尝试使用如我所提到的变量并使用了FOR循环,它遍历了问题,但是我的输出是完全错误的:8
\ $ \ endgroup \ $
– Ryan Schreiber
13年2月16日在20:19

\ $ \ begingroup \ $
@Ryan您本身不需要定义变量。您只需要创建一个包含10个输入的列表。换句话说,您想要这样的东西:[input('输入一个值:')表示范围(0,10)中的i]。该列表理解将转换为10个值的列表,而不必定义10个单独的变量。
\ $ \ endgroup \ $
–πόδαςὠκύς
13年2月16日在21:02



\ $ \ begingroup \ $
@ user1775603,是的,谢谢,我现在开始意识到这一点。 WAAYY更容易做到这一点。它非常酷。
\ $ \ endgroup \ $
– Ryan Schreiber
13年2月17日在11:12

#5 楼

我会做这样的事情:

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'


is_odd函数正在检查整数的最后一位,以查看是否设置了(1)或未设置(0) 。如果设置,则必须为奇数。例如:010(2不是奇数)011(3是奇数)。

此外,我会即时过滤赔率,因此我不需要多次解析列表,因此可以使用xrange (一个生成器)来保持内存“安全”。对于这种情况,这些“优化”将不是必需的,因为列表只有大小10并且没有太多计算,但是如果您必须需要很多整数,您需要考虑一下。

评论


\ $ \ begingroup \ $
使用python3,我更喜欢range,因为它经过优化可以进行惰性评估。 xrange ..在阅读时感觉不好。 :P
\ $ \ endgroup \ $
–马赫什
13年2月17日在9:11

#6 楼

由于您没有指定使用的是Python 2还是Python 3,因此我不确定以下答案是否相关。在Python 2中,input有风险。在Python 3中,input很好。

尽管有些答案已将input(...)替换为int(raw_input(...)),但我认为还没有人解释为什么推荐这样做。


在Python 2.x中被认为是有害的input

在Python 2.x中,input(x)等同于eval(raw_input(x))。例如,请参阅Python 2.7中的input文档和raw_input文档。这意味着用户可以执行任意Python表达式,例如:

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


因此,在Python 2中,始终使用raw_input而不是input

一些解释:raw_input返回一个字符串,例如'10'。您需要将此字符串转换为数字。函数int可以为您完成此操作(请参阅Python 2.7中的文档)。因此,无论您使用input在何处获取整数,都希望使用int(raw_input(...))。这会将输入作为字符串,并立即将其转换为整数。如果输入不能转换为整数,则会引发异常:

>>> 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")'


在Python 3中,input等同于Python 2 raw_input,例如,参见文档适用于Python 3.3中的input

评论


\ $ \ begingroup \ $
我明白了。我正在尝试创建该程序,当我使用raw_input时,它不会运行,即时消息使用python2.7,但它却接受了输入并起作用。为什么会这样呢?并感谢您的见解
\ $ \ endgroup \ $
– Ryan Schreiber
13年2月17日在10:56

\ $ \ begingroup \ $
@RyanSchreiber我添加了一些解释
\ $ \ endgroup \ $
– Gerrit
13年2月17日在11:00

\ $ \ begingroup \ $
太好了,好吧,我现在知道为什么它不起作用了!关于此的另一点说明,为什么我作为一名程序员希望将文本输入为字符串并转换为整数?这是一种安全的编程方式吗?如果是的话,其背后的原因是什么?顺便说一句,是的,我将阅读该文档,就像它上的另一个外部视图一样:)
\ $ \ endgroup \ $
– Ryan Schreiber
13年2月17日在11:07



\ $ \ begingroup \ $
当然,您的意思是raw_input而不是input
\ $ \ endgroup \ $
– Janus Troelsen
13年2月17日在13:55

\ $ \ begingroup \ $
@Ysangkok糟糕,是的,我当然知道了,现在已解决。
\ $ \ endgroup \ $
– Gerrit
2013年2月17日14:39



#7 楼

这是John V. Guttag撰写的《使用Python计算和编程入门》第二章的手指​​练习。这是MITx的推荐文本:6.00x《计算机科学与编程简介》。这本书是为与Python 2.7一起使用而编写的。我知道我正在努力。为此,这是我编写的代码:

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'`


似乎可以工作。可以将其缩短,但其想法是仅使用本书中涉及的有限概念。

经过编辑以包含缩短代码的注释。仍然符合使用本书中介绍的有限概念的标准。

评论


\ $ \ begingroup \ $
我指的是文本中的确切问题。我现在更改了。
\ $ \ endgroup \ $
–archery1234
13年9月9日在2:46

\ $ \ begingroup \ $
哦,好吧。起初似乎是一个新问题。
\ $ \ endgroup \ $
– Jamal♦
13年9月9日在2:48

\ $ \ begingroup \ $
ans = ans不执行任何操作,您可以将所有if ... else ... elif条件简化为一个条件:if counter == 10或(x%2 and x> ans):ans = x
\ $ \ endgroup \ $
–斯图尔特
13年10月10日14:04

\ $ \ begingroup \ $
是的,绝对可以缩短它。最终,我将绕过计算的思维方式。
\ $ \ endgroup \ $
–archery1234
13年13月13日在4:29

\ $ \ begingroup \ $
我建议:如果循环内有x%2和(ans为None或x> ans),并且循环后ans不为None,则ans =无。不重复10和%2将使代码更具可维护性。 (最终结果是@andrewcooke的答案,除非不使用range()。)
\ $ \ endgroup \ $
– 200_success
13年11月14日在18:26



#8 楼

我认为在这种情况下,性能无关紧要,因此优先考虑的是使程序的工作尽可能立即显而易见。

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


每行都是新的逻辑和简洁的步骤。


使用Python 3中的input或Python 2中的raw_input作为字符串从用户获取数字。
将字符串转换为整数。
提取所有字符串数字列表中的奇数。
打印最大的奇数或消息。


#9 楼

为什么不将每个值乘以其最低有效位(也就是模2中的那个数字),以使偶数为零而奇数保持原样,然后使用max()返回最大数(必须为奇数,因为所有偶数乘以零)

**请注意,假设没有负数,那么除了使用max还要从数组中去除所有“ 0”之外。

评论


\ $ \ begingroup \ $
Modulo 2将所有内容映射到0或1,这是没有用的。
\ $ \ endgroup \ $
– 200_success
13年9月9日在5:54

\ $ \ begingroup \ $
@ 200_success如果您阅读完整的答案,您会看到我说乘以2为模的数字本身……这将使所有偶数为0,所有奇数保持原样(因为它们被相乘) 1),然后使用max()并返回最大数(根据定义,这将是最大的ODD数)。
\ $ \ endgroup \ $
–阿尔伯特·伦肖
13年9月9日在6:40

\ $ \ begingroup \ $
@ 200_success如果您可以撤消不赞成投票,将不胜感激。
\ $ \ endgroup \ $
–阿尔伯特·伦肖
13年9月9日在6:43

\ $ \ begingroup \ $
为了清楚起见,我更改了措词并推翻了我的投票。
\ $ \ endgroup \ $
– 200_success
13年9月9日在6:54

\ $ \ begingroup \ $
@ 200_success非常感谢:)这对我来说意味着很多哈哈!
\ $ \ endgroup \ $
–阿尔伯特·伦肖
13年10月10日在5:54