Python如何处理列表中的多个条件?
我试图从我拥有的函数中创建一个列表理解,我遇到了一个意外的行为。为了更好地理解,我的函数获取一个整数,并检查它的哪个数字精确地除以整数:Python如何处理列表中的多个条件?,python,list,Python,List,我试图从我拥有的函数中创建一个列表理解,我遇到了一个意外的行为。为了更好地理解,我的函数获取一个整数,并检查它的哪个数字精确地除以整数: # Full function divs = list() for i in str(number): digit = int(i) if digit > 0 and number % digit == 0: divs.append(digit) return len(divs) # List comprehension
# Full function
divs = list()
for i in str(number):
digit = int(i)
if digit > 0 and number % digit == 0:
divs.append(digit)
return len(divs)
# List comprehension
return len([x for x in str(number) if x > 0 and number % int(x) == 0])
问题是,如果我给出一个1012
作为输入,完整函数将返回3
,这是预期的结果。列表理解返回一个zerodivision错误:整数除法或模乘零
。我理解这是因为这种情况:
if x > 0 and number % int(x) == 0
在full函数中,多重条件是从左到右处理的,因此可以。在列表理解中,我真的不知道,但我猜它不是以同样的方式处理的
直到我尝试使用更简单的函数:
# Full function
positives = list()
for i in numbers:
if i > 0 and 20 % i ==0:
positives.append(i)
return positives
# List comprehension
return [i for i in numbers if i > 0 and 20 % i == 0]
他们俩都工作了。所以我在想,这可能与
数字%int(x)
有关?这只是好奇这到底是怎么回事?有什么想法吗?列表理解是不同的,因为您比较x>0
,而没有将x
转换为int
。在Py2中,不匹配的类型将在an中进行比较,在这种情况下,所有str
s(类型x
)都大于所有int
(类型0
),这意味着x>0
测试总是True
,第二个测试总是执行(请参见下面的脚注,了解这一废话的详细信息)。将列表理解更改为:
[x for x in str(number) if int(x) > 0 and number % int(x) == 0]
它会起作用的
请注意,通过在代码顶部导入Py3版本的map
(来自未来的内置导入map
),并使用带sum
的生成器表达式,而不是带len
的列表理解,可以进一步简化(并限制冗余工作和内存消耗):
return sum(1 for i in map(int, str(number)) if i > 0 and number % i == 0)
每个数字只调用int
一次,不构造中间列表
脚注:0
是一种数字类型,所有数字类型都“更小”比除None
以外的任何东西都大,因此str
总是大于0
。在非数字情况下,它将比较字符串类型名称,因此dict
frozenset列表集str
元组,除了oops、frozenset
和集ode>彼此“自然”比较,这样就可以建立非传递关系;frozenset()<[]
为true;[]
为true,但frozenset()
为false,因为特定于类型的比较器在最终版本中被调用。正如我所说,它是任意的、令人困惑的;它是出于某种原因从Python 3中删除的。您应该说int(x)>列表中的0理解我很惊讶,在将x与0进行比较时,您会得到一个ZeroDivisionError
而不是TypeError
,即str>int
@RNar:在Py2中,不匹配的类型比较不会引发异常(除非自定义比较器代码有意参与)。他们使用回退比较,获得“任意但一致的顺序”;该回退的简单版本是,它比较每种类型的字符串名称。啊,我明白了。py3为此引发了一个显式错误,因此我无法复制。是的。他们在py3中更改了它,正是因为回退比较不直观,可能的错误会悄悄传递。更改的主要受害者是它会打断一些代码,这些代码不是过滤添加到列表中的值,而是插入None
以指示“无值”。对这样的列表进行排序将所有None
移到前面(我认为这是一个巧合,None
是唯一一个type
以大写字母开头的东西,NoneType
使其排序优先于其他任何东西;事实证明,None
实际上是明确的特例,在CPython中是“最小的”)有趣的是,Python 3明确警告:TypeError:unorderable types:str()>int(),它提供一个字符串列表,而不是整数列表-添加另一个int
或简单地迭代map(int,str(number))
取而代之。@RomanSusi是的,这种行为在3.x中发生了改变;请参阅@jornsharpe:由于OP只是检查长度,而不是使用列表,因此结果列表中的值类型不重要。我只是添加了一个更好的解决方案,避免重复int
-id和中间列表
当他们想要的只是一个通过过滤器的值的计数时。谢谢你们!我觉得有点愚蠢,因为我忘记了int(x)
,但我发现这个主题真的很有趣…所以我把它给我了,这很好:P