2
>>> odd,even=[ ],[ ]
>>> [even.append(x) if x%2==0 else odd.append(x) for x in range(51)]
[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]
>>> odd
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49]

我的问题:是否可以在列表理解语句中将奇数和偶数分开,即使没有odd, even = [], []在开头声明?

4

8 回答 8

7

最好只循环一次。这是6条线,但它们是快速线

odd, even=[ ], [ ]
for x in range(51):
    if x%2:
        odd.append(x)
    else:
        even.append(x)
于 2012-05-22T10:46:10.073 回答
6
even,odd = [],[]
for x in range(51): 
    (odd if x%2 else even).append(x)
于 2012-05-22T11:54:53.547 回答
4

考虑这个

evens = [i for i in xrange(1,1000) if i % 2]
odds = [i for i in xrange(1,1000) if i % 2 != 0]
于 2012-05-22T10:43:34.607 回答
4
>>> even, odd = [[x for x in range(51) if x%2 == 0], [x for x in range(51) if x%2 == 1]]
>>> even
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50]
>>> odd
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49]

我不推荐这种方法,但我猜这是一种你可以用“只有一个循环”来做到的方法:

>>> even, odd = zip(*[(x, x + 1) for x in range(0, 51, 2)])
>>> even
(0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50)
>>> odd
(1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51)
于 2012-05-22T10:44:33.947 回答
3

我想提请注意itertools,特别是 Python 帮助中的itertools 食谱。在这里我们可以使用该partition函数(向后移植到 Python 2.7)

from itertools import tee, ifilter, ifilterfalse

def partition(pred, iterable):
    'Use a predicate to partition entries into false entries and true entries'
    # partition(is_odd, range(10)) --> 0 2 4 6 8   and  1 3 5 7 9
    t1, t2 = tee(iterable)
    return ifilterfalse(pred, t1), ifilter(pred, t2)

def is_odd(n):
    return bool(n%2)

evens, odds = partition(is_odd, range(51))

print list(evens)
print list(odds)

事实上,文档字符串中的示例准确地解释了这种情况下的使用。它返回迭代器,因此需要list在打印时使用。

于 2012-05-22T14:08:42.860 回答
2

如果这是一个为了方便而使用数字的简化问题,那么我的答案是不相关的,但是执行您所要求的最简单的方法实际上是:

>>> odd, even = range(1, 51, 2), range(0, 51, 2)

这给了你:

>>> list(odd)
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49]
>>> list(even)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50]
于 2012-05-22T11:34:04.693 回答
1

试试这个版本:对我来说优雅、紧凑、易于理解

even,odd = [],[]
for x in range(51): x%2 and even.append(x) or odd.append(x)
于 2012-05-22T11:02:45.777 回答
1

解决一般问题:

给定一个谓词函数predicate返回一个对象,True或者False当给定一个对象时,根据谓词将一个列表分成两个子列表,同时保留顺序

sorted然后我们可以使用函数是稳定的这一事实,因此如果我们使用predicateas 键进行排序,则列表在未知点被有效地分成两部分,同时保留每个部分内的顺序,其中谓词False在左侧的值和值它True在右边。

现在我们可以使用itertools.groupby相同的密钥在这个未知点进行拆分。

from itertools import groupby

predicate = lambda x: x % 2 == 0

def group_by_predicate(L, pred):
    return [list(i) for k, i in groupby(sorted(L, key=pred), key=pred)]

odd, even = group_by_predicate(range(51), predicate)

即使 is 的值不是均匀间隔的,这也会起作用predicate......True例如,如果predicateTrue素数。

于 2012-05-22T13:02:57.657 回答