【发布时间】:2021-10-13 15:20:27
【问题描述】:
我正在编写一个函数,它将列表划分为(几乎)相等的“n”个分布。我希望这个函数返回一个生成器,但生成生成器似乎存在问题。该函数适用于可迭代对象。看看这个sn-p:
import itertools
def divide_list(array, n, gen_length=None):
"""
:param array: some iterable that you wish to divide
:param n: the number of lists you would like to return
:param gen_length: The length of the generator if array is a generator. Not necessary for lists and tuples.
:return: a generator of the divided list
Example:
In: list(divide_list([1, 2, 3, 4, 5, 6, 7, 8, 9], 4))
Out: [[1, 2, 3], [4, 5], [6, 7], [8, 9]]
"""
if isinstance(array, (list, tuple)):
floor, rem = divmod(len(array), n)
items_index = (0, floor)
for _ in range(n):
prev, next_ = items_index[0], items_index[1] + 1 if rem > 0 else items_index[1]
yield array[prev:next_]
items_index = (next_, next_ + floor)
rem -= 1
else:
floor, rem = divmod(gen_length, n)
items_index = (0, floor)
for _ in range(n):
prev, next_ = items_index[0], items_index[1] + 1 if rem > 0 else items_index[1]
yield itertools.islice(array, prev, next_)
items_index = (next_, next_ + floor)
rem -= 1
if __name__ == '__main__':
array_ = iter([12, 7, 9, 31, 13, 11, 7, 3])
print('Generator:')
print('----------')
for value in divide_list(array_, 3, gen_length=8):
print(list(value))
print('')
array_ = [12, 7, 9, 31, 13, 11, 7, 3]
print('List:')
print('-----')
for value in divide_list(array_, 3):
print(value)
这是输出:
Generator:
----------
[12, 7, 9]
[7, 3]
[]
List:
-----
[12, 7, 9]
[31, 13, 11]
[7, 3]
为什么最后一台发电机耗尽?有时,它会耗尽最后两个生成器。
【问题讨论】:
-
你告诉
islice跳过下一个prev元素。 -
您能详细说明或更改我的代码吗?我希望
islice跳到prev并转到next_然后再做同样的事情直到它到达列表的末尾。 @KellyBundy -
“我想让 islice 跳到
prev”——不,你不会。您认为要跳过的内容已经从迭代器中删除。您不想跳过任何内容。 -
不,这与我所说的相反。我的意思是你忘记了你已经切掉了元素,所以你不应该尝试另外跳过它们。这些命令中的第二个不应使用
3, 6,而应使用0, 3。 -
顺便说一句,这两种情况没必要分开处理。您可以将所有内容都视为迭代器。
标签: python generator itertools