我有一个Python脚本,它将整数列表作为输入,我需要一次使用四个整数。不幸的是,我无法控制输入,或者我将它作为四元素元组列表传入。目前,我正在以这种方式迭代:
for i in xrange(0, len(ints), 4):
# dummy op for example code
foo += ints[i] * ints[i + 1] + ints[i + 2] * ints[i + 3]
它看起来很像“C-think”,但这让我怀疑有更多的pythonic方式来处理这种情况。迭代后会丢弃该列表,因此无需保留。也许这样的事情会更好吗?
while ints:
foo += ints[0] * ints[1] + ints[2] * ints[3]
ints[0:4] = []
但是,仍然没有“感觉”正确。 : - /
相关问题:How do you split a list into evenly sized chunks in Python?
答案 0 :(得分:364)
def chunker(seq, size):
return (seq[pos:pos + size] for pos in range(0, len(seq), size))
# (in python 2 use xrange() instead of range() to avoid allocating a list)
简单。简单。快速。适用于任何序列:
text = "I am a very, very helpful text"
for group in chunker(text, 7):
print repr(group),
# 'I am a ' 'very, v' 'ery hel' 'pful te' 'xt'
print '|'.join(chunker(text, 10))
# I am a ver|y, very he|lpful text
animals = ['cat', 'dog', 'rabbit', 'duck', 'bird', 'cow', 'gnu', 'fish']
for group in chunker(animals, 3):
print group
# ['cat', 'dog', 'rabbit']
# ['duck', 'bird', 'cow']
# ['gnu', 'fish']
答案 1 :(得分:282)
从Python recipes文档的itertools部分修改:
from itertools import zip_longest
def grouper(iterable, n, fillvalue=None):
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
示例强>
在伪代码中保持示例简洁。
grouper('ABCDEFG', 3, 'x') --> 'ABC' 'DEF' 'Gxx'
Python 2上的 注意:使用izip_longest
而不是zip_longest
。
答案 2 :(得分:109)
我是
的粉丝chunk_size= 4
for i in range(0, len(ints), chunk_size):
chunk = ints[i:i+chunk_size]
# process chunk of size <= chunk_size
答案 3 :(得分:20)
import itertools
def chunks(iterable,size):
it = iter(iterable)
chunk = tuple(itertools.islice(it,size))
while chunk:
yield chunk
chunk = tuple(itertools.islice(it,size))
# though this will throw ValueError if the length of ints
# isn't a multiple of four:
for x1,x2,x3,x4 in chunks(ints,4):
foo += x1 + x2 + x3 + x4
for chunk in chunks(ints,4):
foo += sum(chunk)
另一种方式:
import itertools
def chunks2(iterable,size,filler=None):
it = itertools.chain(iterable,itertools.repeat(filler,size-1))
chunk = tuple(itertools.islice(it,size))
while len(chunk) == size:
yield chunk
chunk = tuple(itertools.islice(it,size))
# x2, x3 and x4 could get the value 0 if the length is not
# a multiple of 4.
for x1,x2,x3,x4 in chunks2(ints,4,0):
foo += x1 + x2 + x3 + x4
答案 4 :(得分:11)
from itertools import izip_longest
def chunker(iterable, chunksize, filler):
return izip_longest(*[iter(iterable)]*chunksize, fillvalue=filler)
答案 5 :(得分:9)
我需要一个也适用于集合和生成器的解决方案。我无法想出任何非常简短的东西,但至少它是可读的。
def chunker(seq, size):
res = []
for el in seq:
res.append(el)
if len(res) == size:
yield res
res = []
if res:
yield res
列表:
>>> list(chunker([i for i in range(10)], 3))
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
集:
>>> list(chunker(set([i for i in range(10)]), 3))
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
发电机:
>>> list(chunker((i for i in range(10)), 3))
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
答案 6 :(得分:7)
此问题的理想解决方案适用于迭代器(不仅仅是序列)。它也应该很快。
这是itertools文档提供的解决方案:
def grouper(n, iterable, fillvalue=None):
#"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return itertools.izip_longest(fillvalue=fillvalue, *args)
在我的Mac书籍空气中使用ipython的%timeit
,每循环获得47.5 us。
但是,这对我来说真的不起作用,因为结果被填充为偶数组。没有填充的解决方案稍微复杂一些。最天真的解决方案可能是:
def grouper(size, iterable):
i = iter(iterable)
while True:
out = []
try:
for _ in range(size):
out.append(i.next())
except StopIteration:
yield out
break
yield out
简单但很慢:每个循环693 us
我能提出的最佳解决方案是使用islice
作为内循环:
def grouper(size, iterable):
it = iter(iterable)
while True:
group = tuple(itertools.islice(it, None, size))
if not group:
break
yield group
使用相同的数据集,我得到每个循环305 us。
无法以更快的速度获得纯解决方案,我提供以下解决方案并提出一个重要警告:如果您的输入数据中包含filldata
个实例,则可能会得到错误答案。
def grouper(n, iterable, fillvalue=None):
#"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
for i in itertools.izip_longest(fillvalue=fillvalue, *args):
if tuple(i)[-1] == fillvalue:
yield tuple(v for v in i if v != fillvalue)
else:
yield i
我真的不喜欢这个答案,但速度要快得多。每循环124 us
答案 7 :(得分:7)
在Python 3.8中,您可以使用walrus运算符和itertools.islice
。
from itertools import islice
list_ = [i for i in range(10, 100)]
def chunker(it, size):
iterator = iter(it)
while chunk := list(islice(iterator, size)):
print(chunk)
In [2]: chunker(list_, 10)
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39]
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49]
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59]
[60, 61, 62, 63, 64, 65, 66, 67, 68, 69]
[70, 71, 72, 73, 74, 75, 76, 77, 78, 79]
[80, 81, 82, 83, 84, 85, 86, 87, 88, 89]
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
答案 8 :(得分:7)
与其他提案类似,但不完全相同,我喜欢这样做,因为它简单易读:
it = iter([1, 2, 3, 4, 5, 6, 7, 8, 9])
for chunk in zip(it, it, it, it):
print chunk
>>> (1, 2, 3, 4)
>>> (5, 6, 7, 8)
这样你就不会获得最后一个部分块。如果您想将(9, None, None, None)
作为最后一个块,请使用izip_longest
中的itertools
。
答案 9 :(得分:5)
由于没有人提到它,这里是一个zip()
解决方案:
>>> def chunker(iterable, chunksize):
... return zip(*[iter(iterable)]*chunksize)
仅当序列的长度始终可以被块大小整除时才有效,或者如果不是,则不关心尾随块。
示例:
>>> s = '1234567890'
>>> chunker(s, 3)
[('1', '2', '3'), ('4', '5', '6'), ('7', '8', '9')]
>>> chunker(s, 4)
[('1', '2', '3', '4'), ('5', '6', '7', '8')]
>>> chunker(s, 5)
[('1', '2', '3', '4', '5'), ('6', '7', '8', '9', '0')]
或使用itertools.izip返回迭代器而不是列表:
>>> from itertools import izip
>>> def chunker(iterable, chunksize):
... return izip(*[iter(iterable)]*chunksize)
可以使用@ΤΖΩΤΖΙΟΥ's answer:
修复填充>>> from itertools import chain, izip, repeat
>>> def chunker(iterable, chunksize, fillvalue=None):
... it = chain(iterable, repeat(fillvalue, chunksize-1))
... args = [it] * chunksize
... return izip(*args)
答案 10 :(得分:5)
使用map()代替zip()修复了J.F.Sebastian回答中的填充问题:
>>> def chunker(iterable, chunksize):
... return map(None,*[iter(iterable)]*chunksize)
示例:
>>> s = '1234567890'
>>> chunker(s, 3)
[('1', '2', '3'), ('4', '5', '6'), ('7', '8', '9'), ('0', None, None)]
>>> chunker(s, 4)
[('1', '2', '3', '4'), ('5', '6', '7', '8'), ('9', '0', None, None)]
>>> chunker(s, 5)
[('1', '2', '3', '4', '5'), ('6', '7', '8', '9', '0')]
答案 11 :(得分:4)
more-itertools程序包具有chunked方法,该方法完全可以做到:
import more_itertools
for s in more_itertools.chunked(range(9), 4):
print(s)
打印
[0, 1, 2, 3]
[4, 5, 6, 7]
[8]
chunked
返回列表中的项目。如果您更喜欢可迭代,请使用ichunked。
答案 12 :(得分:4)
如果您不介意使用外部包,可以使用iteration_utilities.grouper
1 中的iteration_utilties
。它支持所有迭代(不仅仅是序列):
from iteration_utilities import grouper
seq = list(range(20))
for group in grouper(seq, 4):
print(group)
打印:
(0, 1, 2, 3)
(4, 5, 6, 7)
(8, 9, 10, 11)
(12, 13, 14, 15)
(16, 17, 18, 19)
如果长度不是groupsize的倍数,它还支持填充(不完整的最后一组)或截断(丢弃不完整的最后一组)最后一个:
from iteration_utilities import grouper
seq = list(range(17))
for group in grouper(seq, 4):
print(group)
# (0, 1, 2, 3)
# (4, 5, 6, 7)
# (8, 9, 10, 11)
# (12, 13, 14, 15)
# (16,)
for group in grouper(seq, 4, fillvalue=None):
print(group)
# (0, 1, 2, 3)
# (4, 5, 6, 7)
# (8, 9, 10, 11)
# (12, 13, 14, 15)
# (16, None, None, None)
for group in grouper(seq, 4, truncate=True):
print(group)
# (0, 1, 2, 3)
# (4, 5, 6, 7)
# (8, 9, 10, 11)
# (12, 13, 14, 15)
1 免责声明:我是该套餐的作者。
答案 13 :(得分:3)
使用小功能和东西真的不吸引我;我更喜欢使用切片:
data = [...]
chunk_size = 10000 # or whatever
chunks = [data[i:i+chunk_size] for i in xrange(0,len(data),chunk_size)]
for chunk in chunks:
...
答案 14 :(得分:3)
如果列表很大,执行此操作的最佳方法是使用生成器:
def get_chunk(iterable, chunk_size):
result = []
for item in iterable:
result.append(item)
if len(result) == chunk_size:
yield tuple(result)
result = []
if len(result) > 0:
yield tuple(result)
for x in get_chunk([1,2,3,4,5,6,7,8,9,10], 3):
print x
(1, 2, 3)
(4, 5, 6)
(7, 8, 9)
(10,)
答案 15 :(得分:2)
除非我有任何遗漏,否则未提及使用生成器表达式的以下简单解决方案。假定块的大小和数量都是已知的(通常是这种情况),并且不需要填充:
def chunks(it, n, m):
"""Make an iterator over m first chunks of size n.
"""
it = iter(it)
# Chunks are presented as tuples.
return (tuple(next(it) for _ in range(n)) for _ in range(m))
答案 16 :(得分:2)
另一种方法是使用iter
的双参数形式:
from itertools import islice
def group(it, size):
it = iter(it)
return iter(lambda: tuple(islice(it, size)), ())
这可以很容易地使用填充(这类似于Markus Jarderot的答案):
from itertools import islice, chain, repeat
def group_pad(it, size, pad=None):
it = chain(iter(it), repeat(pad))
return iter(lambda: tuple(islice(it, size)), (pad,) * size)
这些甚至可以组合用于可选填充:
_no_pad = object()
def group(it, size, pad=_no_pad):
if pad == _no_pad:
it = iter(it)
sentinel = ()
else:
it = chain(iter(it), repeat(pad))
sentinel = (pad,) * size
return iter(lambda: tuple(islice(it, size)), sentinel)
答案 17 :(得分:2)
使用NumPy很简单:
ints = array([1, 2, 3, 4, 5, 6, 7, 8])
for int1, int2 in ints.reshape(-1, 2):
print(int1, int2)
输出:
1 2
3 4
5 6
7 8
答案 18 :(得分:1)
def group_by(iterable, size):
"""Group an iterable into lists that don't exceed the size given.
>>> group_by([1,2,3,4,5], 2)
[[1, 2], [3, 4], [5]]
"""
sublist = []
for index, item in enumerate(iterable):
if index > 0 and index % size == 0:
yield sublist
sublist = []
sublist.append(item)
if sublist:
yield sublist
答案 19 :(得分:1)
我从不希望我的大块填充,所以这个要求是必不可少的。我发现能够处理任何可迭代的能力也是必需的。鉴于此,我决定延续接受的答案https://stackoverflow.com/a/434411/1074659。
如果由于需要比较和过滤填充值而不需要填充,则此方法会略微受到影响。但是,对于大块大小,此实用程序非常高效。
#!/usr/bin/env python3
from itertools import zip_longest
_UNDEFINED = object()
def chunker(iterable, chunksize, fillvalue=_UNDEFINED):
"""
Collect data into chunks and optionally pad it.
Performance worsens as `chunksize` approaches 1.
Inspired by:
https://docs.python.org/3/library/itertools.html#itertools-recipes
"""
args = [iter(iterable)] * chunksize
chunks = zip_longest(*args, fillvalue=fillvalue)
yield from (
filter(lambda val: val is not _UNDEFINED, chunk)
if chunk[-1] is _UNDEFINED
else chunk
for chunk in chunks
) if fillvalue is _UNDEFINED else chunks
答案 20 :(得分:1)
我喜欢这种方法。它感觉简单而不神奇,支持所有可迭代类型,并且不需要导入。
def chunk_iter(iterable, chunk_size):
it = iter(iterable)
while True:
chunk = tuple(next(it) for _ in range(chunk_size))
if not chunk:
break
yield chunk
答案 21 :(得分:1)
app.directive("autoLoad", function ($window) {
return {
scope: {
do: '&'
},
controller : function($scope, $element) {
var scroller = $element;
angular.element($window).bind("scroll", function() {
if(($(window).scrollTop() + $(window).height()) > ($(document).height() - 100)) {
console.log("GOT HERE!");
$scope.do(); // LOAD POSTS
}
});
}
};
答案 22 :(得分:1)
这是一个没有支持生成器的导入的chunker:
def chunks(seq, size):
it = iter(seq)
while True:
ret = tuple(next(it) for _ in range(size))
if len(ret) == size:
yield ret
else:
raise StopIteration()
使用示例:
>>> def foo():
... i = 0
... while True:
... i += 1
... yield i
...
>>> c = chunks(foo(), 3)
>>> c.next()
(1, 2, 3)
>>> c.next()
(4, 5, 6)
>>> list(chunks('abcdefg', 2))
[('a', 'b'), ('c', 'd'), ('e', 'f')]
答案 23 :(得分:1)
关于J.F. Sebastian
here提供的解决方案:
def chunker(iterable, chunksize):
return zip(*[iter(iterable)]*chunksize)
它很聪明,但有一个缺点 - 总是返回元组。如何换取字符串?
当然你可以写''.join(chunker(...))
,但无论如何都会构建临时元组。
您可以通过编写自己的zip
来删除临时元组,如下所示:
class IteratorExhausted(Exception):
pass
def translate_StopIteration(iterable, to=IteratorExhausted):
for i in iterable:
yield i
raise to # StopIteration would get ignored because this is generator,
# but custom exception can leave the generator.
def custom_zip(*iterables, reductor=tuple):
iterators = tuple(map(translate_StopIteration, iterables))
while True:
try:
yield reductor(next(i) for i in iterators)
except IteratorExhausted: # when any of iterators get exhausted.
break
然后
def chunker(data, size, reductor=tuple):
return custom_zip(*[iter(data)]*size, reductor=reductor)
使用示例:
>>> for i in chunker('12345', 2):
... print(repr(i))
...
('1', '2')
('3', '4')
>>> for i in chunker('12345', 2, ''.join):
... print(repr(i))
...
'12'
'34'
答案 24 :(得分:1)
避免所有转化为列表import itertools
和:
>>> for k, g in itertools.groupby(xrange(35), lambda x: x/10):
... list(g)
产地:
...
0 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1 [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
2 [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
3 [30, 31, 32, 33, 34]
>>>
我检查了groupby
并且它没有转换为列表或使用len
所以我(想)这会延迟每个值的解析,直到实际使用它为止。可悲的是,没有任何可用的答案(此时)似乎提供了这种变化。
显然,如果您需要依次处理每个项目,请在g:
上嵌套for循环for k,g in itertools.groupby(xrange(35), lambda x: x/10):
for i in g:
# do what you need to do with individual items
# now do what you need to do with the whole group
我对此的特别兴趣是需要使用生成器将最多1000个批次的更改提交给gmail API:
messages = a_generator_which_would_not_be_smart_as_a_list
for idx, batch in groupby(messages, lambda x: x/1000):
batch_request = BatchHttpRequest()
for message in batch:
batch_request.add(self.service.users().messages().modify(userId='me', id=message['id'], body=msg_labels))
http = httplib2.Http()
self.credentials.authorize(http)
batch_request.execute(http=http)
答案 25 :(得分:1)
您可以使用partition库中的chunks或funcy功能:
from funcy import partition
for a, b, c, d in partition(4, ints):
foo += a * b * c * d
这些函数还有迭代器版本ipartition
和ichunks
,在这种情况下效率会更高。
您还可以查看their implementation。
答案 26 :(得分:1)
又一个答案,其优点是:
1)容易理解的
2)适用于任何可迭代的,而不仅仅是序列(上面的一些答案会阻碍文件句柄)
3)不要一次性将块加载到内存中
4)不要在内存中创建一个长度相同的迭代器列表
5)列表末尾没有填充填充值
话虽如此,我还没有计时,所以它可能比一些更聪明的方法更慢,并且考虑到用例,一些优点可能无关紧要。
def chunkiter(iterable, size):
def inneriter(first, iterator, size):
yield first
for _ in xrange(size - 1):
yield iterator.next()
it = iter(iterable)
while True:
yield inneriter(it.next(), it, size)
In [2]: i = chunkiter('abcdefgh', 3)
In [3]: for ii in i:
for c in ii:
print c,
print ''
...:
a b c
d e f
g h
<强>更新强>
由于内环和外环从相同的迭代器中提取值,因此存在一些缺点:
1)continue在外部循环中没有按预期工作 - 它只是继续到下一个项目而不是跳过一个块。然而,这似乎不是一个问题,因为在外循环中没有什么可测试的
2)break在内循环中没有按预期工作 - 控件将在迭代器中的下一个项目中再次在内循环中结束。要跳过整个块,要么将内部迭代器(上面的ii)包装在一个元组中,例如for c in tuple(ii)
,或设置一个标志并耗尽迭代器。
答案 27 :(得分:1)
在你的第二种方法中,我会通过这样做前进到下一组4:
ints = ints[4:]
但是,我没有进行任何性能测量,因此我不知道哪一个可能更有效。
话虽如此,我通常会选择第一种方法。它并不漂亮,但这通常是与外界联系的结果。
答案 28 :(得分:0)
为什么不使用列表理解
l = [1 , 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
n = 4
filler = 0
fills = len(l) % n
chunks = ((l + [filler] * fills)[x * n:x * n + n] for x in range(int((len(l) + n - 1)/n)))
print(chunks)
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 0]]
答案 29 :(得分:0)
这是我在列表、迭代器和范围上的工作......懒惰:
def chunker(it,size):
rv = []
for i,el in enumerate(it,1) :
rv.append(el)
if i % size == 0 :
yield rv
rv = []
if rv : yield rv
几乎是单行的;(
In [95]: list(chunker(range(9),2) )
Out[95]: [[0, 1], [2, 3], [4, 5], [6, 7], [8]]
In [96]: list(chunker([1,2,3,4,5],2) )
Out[96]: [[1, 2], [3, 4], [5]]
In [97]: list(chunker(iter(range(9)),2) )
Out[97]: [[0, 1], [2, 3], [4, 5], [6, 7], [8]]
In [98]: list(chunker(range(9),25) )
Out[98]: [[0, 1, 2, 3, 4, 5, 6, 7, 8]]
In [99]: list(chunker(range(9),1) )
Out[99]: [[0], [1], [2], [3], [4], [5], [6], [7], [8]]
In [101]: %timeit list(chunker(range(101),2) )
11.3 µs ± 68.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
答案 30 :(得分:0)
我希望通过将迭代器从列表中移出,我不会简单地复制列表的一部分。可以对生成器进行切片,它们将自动仍然是生成器,而列表将被切片为1000个条目的巨大块,这会降低效率。
def iter_group(iterable, batch_size:int):
length = len(iterable)
start = batch_size*-1
end = 0
while(end < length):
start += batch_size
end += batch_size
if type(iterable) == list:
yield (iterable[i] for i in range(start,min(length-1,end)))
else:
yield iterable[start:end]
用法:
items = list(range(1,1251))
for item_group in iter_group(items, 1000):
for item in item_group:
print(item)
答案 31 :(得分:0)
似乎没有一种漂亮的方法可以做到这一点。 Here是一个包含多种方法的页面,包括:
def split_seq(seq, size):
newseq = []
splitsize = 1.0/size*len(seq)
for i in range(size):
newseq.append(seq[int(round(i*splitsize)):int(round((i+1)*splitsize))])
return newseq
答案 32 :(得分:0)
此答案拆分字符串列表,f.ex。实现PEP8线长度合规:
def split(what, target_length=79):
'''splits list of strings into sublists, each
having string length at most 79'''
out = [[]]
while what:
if len("', '".join(out[-1])) + len(what[0]) < target_length:
out[-1].append(what.pop(0))
else:
if not out[-1]: # string longer than target_length
out[-1] = [what.pop(0)]
out.append([])
return out
用作
>>> split(['deferred_income', 'long_term_incentive', 'restricted_stock_deferred', 'shared_receipt_with_poi', 'loan_advances', 'from_messages', 'other', 'director_fees', 'bonus', 'total_stock_value', 'from_poi_to_this_person', 'from_this_person_to_poi', 'restricted_stock', 'salary', 'total_payments', 'exercised_stock_options'], 75)
[['deferred_income', 'long_term_incentive', 'restricted_stock_deferred'], ['shared_receipt_with_poi', 'loan_advances', 'from_messages', 'other'], ['director_fees', 'bonus', 'total_stock_value', 'from_poi_to_this_person'], ['from_this_person_to_poi', 'restricted_stock', 'salary', 'total_payments'], ['exercised_stock_options']]
答案 33 :(得分:0)
这里有相当pythonic(你也可以内联split_groups
函数的主体)
import itertools
def split_groups(iter_in, group_size):
return ((x for _, x in item) for _, item in itertools.groupby(enumerate(iter_in), key=lambda x: x[0] // group_size))
for x, y, z, w in split_groups(range(16), 4):
foo += x * y + z * w
答案 34 :(得分:0)
很容易让itertools.groupby
为你提供可迭代的迭代,而无需创建任何临时列表:
groupby(iterable, (lambda x,y: (lambda z: x.next()/y))(count(),100))
不要被嵌套的lambdas推迟,外部lambda只运行一次,将count()
生成器和常量100
放入内部lambda的范围内。
我使用它将行块发送到mysql。
for k,v in groupby(bigdata, (lambda x,y: (lambda z: x.next()/y))(count(),100))):
cursor.executemany(sql, v)
答案 35 :(得分:0)
首先,我设计它将字符串拆分为子字符串以解析包含hex的字符串 今天我把它变成了复杂但仍然很简单的发电机。
def chunker(iterable, size, reductor, condition):
it = iter(iterable)
def chunk_generator():
return (next(it) for _ in range(size))
chunk = reductor(chunk_generator())
while condition(chunk):
yield chunk
chunk = reductor(chunk_generator())
iterable
是包含/生成/迭代输入数据的任何可迭代/迭代器/生成器,size
当然是你想要的大小, reductor
是一个可调用的,它接收生成器迭代chunk的内容
我希望它能够返回序列或字符串,但我不会要求它。
您可以传递此参数,例如list
,tuple
,set
,frozenset
,
或任何更高档的人。我通过这个功能,返回字符串
(假设iterable
包含/生成/遍历字符串):
def concatenate(iterable):
return ''.join(iterable)
请注意,reductor
可能会因引发异常而导致关闭生成器。
condition
是一个可调用的,可以接收reductor
返回的任何内容
它决定批准&amp;屈服它(通过返回评估为True
的任何东西),
或拒绝它&amp;完成生成器的工作(通过返回任何其他内容或引发异常)。
当iterable
中的元素数量不能被size
整除时,当it
耗尽时,reductor
将接收生成的元素少于size
的元素。
我们将这些元素称为持续元素。
我邀请两个函数作为这个参数传递:
lambda x:x
- 持续元素将会产生。
lambda x: len(x)==<size>
- 持续元素将被拒绝
使用等于<size>
的数字替换size
答案 36 :(得分:0)
以大小x
的大小4
迭代列表for a, b, c, d in zip(x[0::4], x[1::4], x[2::4], x[3::4]):
... do something with a, b, c and d ...
的单行,即席解决方案 -
{{1}}
答案 37 :(得分:0)
如果列表大小相同,您可以将它们组合成具有zip()
的4元组列表。例如:
# Four lists of four elements each.
l1 = range(0, 4)
l2 = range(4, 8)
l3 = range(8, 12)
l4 = range(12, 16)
for i1, i2, i3, i4 in zip(l1, l2, l3, l4):
...
以下是zip()
函数产生的内容:
>>> print l1
[0, 1, 2, 3]
>>> print l2
[4, 5, 6, 7]
>>> print l3
[8, 9, 10, 11]
>>> print l4
[12, 13, 14, 15]
>>> print zip(l1, l2, l3, l4)
[(0, 4, 8, 12), (1, 5, 9, 13), (2, 6, 10, 14), (3, 7, 11, 15)]
如果列表很大,并且您不想将它们组合成更大的列表,请使用itertools.izip()
,它生成迭代器而不是列表。
from itertools import izip
for i1, i2, i3, i4 in izip(l1, l2, l3, l4):
...