列表理解建议

时间:2012-05-22 10:39:36

标签: python list-comprehension

>>> 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 = [], [],是否可以将列表理解语句中的奇数和偶数分开?

8 个答案:

答案 0 :(得分:7)

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

odd, even=[ ], [ ]
for x in range(51):
    if x%2:
        odd.append(x)
    else:
        even.append(x)

答案 1 :(得分:6)

even,odd = [],[]
for x in range(51): 
    (odd if x%2 else even).append(x)

答案 2 :(得分:4)

考虑一下

evens = [i for i in xrange(1,1000) if i % 2]
odds = [i for i in xrange(1,1000) if i % 2 != 0]

答案 3 :(得分: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)

答案 4 :(得分:3)

我想提请注意itertools,特别是Python帮助中的itertools recipes。在这里,我们可以使用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)

实际上,docstring中的示例正好解释了这种情况的用法。它返回迭代器,因此在打印时需要使用list

答案 5 :(得分: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]

答案 6 :(得分:1)

解决一般问题:

  

给定谓词函数predicate在给定对象时返回TrueFalse,根据谓词将列表分成两个子列表,同时保留顺序

然后我们可以使用sorted功能稳定的事实,因此如果我们将predicate作为关键字进行排序,则列表有效地分为两部分保留每个部分内的顺序时的未知点,其左侧的谓词为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)

即使predicateTrue的值不均匀,也会有效...例如,如果predicateTrue,则为素数。< / p>

答案 7 :(得分:0)

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

even,odd = [],[]
for x in range(51): x%2 and even.append(x) or odd.append(x)