Python“其他元素”的成语

我觉得我花了很多时间在Python中编写代码,但是没有足够的时间来创buildPythonic代码。 最近我遇到了一个有趣的小问题,我想可能有一个简单,习惯的解决scheme。 解释原文,我需要收集列表中的每一个顺序对。 例如,给出列表[1,2,3,4,5,6] ,我想计算[(1,2),(3,4),(5,6)]

当时我提出了一个快速的解决scheme,看起来像翻译的Java。 重温这个问题,我能做的最好的是

 l = [1,2,3,4,5,6] [(l[2*x],l[2*x+1]) for x in range(len(l)/2)] 

在长度不均匀的情况下,具有抛出最后一个数字的副作用。

有没有一个更习惯的方法,我错过了,或者这是我会得到最好的?

这将做得更整齐一点:

 >>> data = [1,2,3,4,5,6] >>> zip(data[0::2], data[1::2]) [(1, 2), (3, 4), (5, 6)] 

(但是,如果你不熟悉范围的“步幅”特征,那么它的可读性就更差了)。

就像你的代码一样,它会丢弃你有奇数个值的最后一个值。

经常引用的是:

 zip(*[iter(l)] * 2) 

我通常将itertools文档中的grouper配方复制到我的代码中。

 def grouper(n, iterable, fillvalue=None): "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" args = [iter(iterable)] * n return izip_longest(fillvalue=fillvalue, *args) 

如何使用range()的step属性:

 [(l[n],l[n+1]) for n in range(0,len(l),2)] 

尝试这个

 def pairs(l, n): return zip(*[l[i::n] for i in range(n)]) 

所以,

pairs([1, 2, 3, 4], 2)给出

 [(1, 2), (3, 4)] 

正确的事情可能不是计算列表,而是编写一个迭代器 – >迭代器函数。 这是更通用的 – 它适用于每一个迭代,如果你想“冻结”到列表中,你可以使用“list()”函数。

 def groupElements(iterable, n): # For your case, you can hardcode n=2, but I wanted the general case here. # Also, you do not specify what to do if the # length of the list is not divisible by 2 # I chose here to drop such elements source = iter(iterable) while True: l = [] for i in range(n): l.append(source.next()) yield tuple(l) 

我很惊讶itertools模块还没有一个function – 可能是未来的修订。 在此之前,请随意使用上面的版本:)

toolz是一个精心打造的库,在itertools中忽略了许多函数式编程的细节。 partition解决了这个问题(用一个选项来填充奇数长度的列表的最后一项)

 >>> list(toolz.partition(2, [1,2,3,4,5,6])) [(1, 2), (3, 4), (5, 6)] 

如果你不想丢失元素,如果他们的列表中的数字甚至不尝试这样的:

 >>> l = [1, 2, 3, 4, 5] >>> [(l[i], l[i+1] if i+1 < len(l) else None) for i in range(0, len(l), 2)] [(1, 2), (3, 4), (5, None)]