如何从可迭代的保持原始索引中枚举选定的元素?
How to enumerate over selected elements from an iterable keeping original indices?
我运行进入在selected元素上使用枚举器的情况,形成一个可迭代(即sequence 或 iterator 或类似的)并希望返回 original 索引 而不是默认值 count
,从 0
开始,一直到 len(iterable) - 1
。
一个非常幼稚的方法是声明一个新的生成器对象,称为_enumerate()
>>> def _enumerate(iterable, offset = 0, step = 1):
index = offset
for element in iterable:
yield index, element
index += step
...一个新的列表对象months
.
>>> months = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"]
使用 Python 内置 enumerate
函数 将为 [5::2]
切片生成此 输出:
>>> for index, element in enumerate(months[5::2]):
print(index, element)
0 June
1 August
2 October
3 December
我们自己的枚举器_enumerate
的预期输出再次用于[5::2]
切片:
>>> for index, element in _enumerate(months[5::2], offset = 5, step = 2):
print(index, element)
5 June
7 August
9 October
11 December
你知道更好、更 pythonic 和更易读的解决方案吗? :)
我不喜欢用range(len(...
,但也许在这里没问题。
>>> months = ["January", "February", "March", "April", "May", "June",
... "July", "August", "September", "October", "November", "December"]
>>> print(*('{:>2} {}'.format(i, months[i]) for i in range(len(months))[5::2]), sep='\n')
5 June
7 August
9 October
11 December
单行展开:
offset = 5
step = 2
r = range(len(months))
for i in r[offset::step]:
print('{:>2} {}'.format(i, months[i]))
import itertools as it
months = [
"January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"
]
print list(
it.islice(it.izip(it.count(1), months), 5, len(months), 2)
)
回答评论中的进一步问题:
普通切片不适用于 itertools.izip
,因为它不支持 __getitem__
方法。
是的,itertools.izip
已从 Python 3 中删除,常规内置 zip
使用相同的生成器语义。
这里是我的评论作为回答;)
months = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"]
offset = 5
step = 2
for index, element in enumerate(months[offset::step]):
# recalculate original index
index = offset + index*step
# actually repetition of the month is trivial,
# but I put it just to show that the index is right
print(index, element, months[index])
打印:
5 June June
7 August August
9 October October
11 December December
您可以使用 itertools.islice()
+ enumerate()
到 select 个具有原始索引的元素:
>>> import calendar
>>> from itertools import islice
>>> for i, month in islice(enumerate(calendar.month_abbr), 6, None, 2):
... print(i, month)
...
6 Jun
8 Aug
10 Oct
12 Dec
它不复制切片信息并使用具有熟悉行为的现有函数。
或者如果你知道原来的iterable很小;你可以打电话给 list()
:
>>> list(enumerate(calendar.month_abbr))[6::2]
[(6, 'Jun'), (8, 'Aug'), (10, 'Oct'), (12, 'Dec')]
我运行进入在selected元素上使用枚举器的情况,形成一个可迭代(即sequence 或 iterator 或类似的)并希望返回 original 索引 而不是默认值 count
,从 0
开始,一直到 len(iterable) - 1
。
一个非常幼稚的方法是声明一个新的生成器对象,称为_enumerate()
>>> def _enumerate(iterable, offset = 0, step = 1):
index = offset
for element in iterable:
yield index, element
index += step
...一个新的列表对象months
.
>>> months = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"]
使用 Python 内置 enumerate
函数 将为 [5::2]
切片生成此 输出:
>>> for index, element in enumerate(months[5::2]):
print(index, element)
0 June
1 August
2 October
3 December
我们自己的枚举器_enumerate
的预期输出再次用于[5::2]
切片:
>>> for index, element in _enumerate(months[5::2], offset = 5, step = 2):
print(index, element)
5 June
7 August
9 October
11 December
你知道更好、更 pythonic 和更易读的解决方案吗? :)
我不喜欢用range(len(...
,但也许在这里没问题。
>>> months = ["January", "February", "March", "April", "May", "June",
... "July", "August", "September", "October", "November", "December"]
>>> print(*('{:>2} {}'.format(i, months[i]) for i in range(len(months))[5::2]), sep='\n')
5 June
7 August
9 October
11 December
单行展开:
offset = 5
step = 2
r = range(len(months))
for i in r[offset::step]:
print('{:>2} {}'.format(i, months[i]))
import itertools as it
months = [
"January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"
]
print list(
it.islice(it.izip(it.count(1), months), 5, len(months), 2)
)
回答评论中的进一步问题:
普通切片不适用于
itertools.izip
,因为它不支持__getitem__
方法。是的,
itertools.izip
已从 Python 3 中删除,常规内置zip
使用相同的生成器语义。
这里是我的评论作为回答;)
months = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"]
offset = 5
step = 2
for index, element in enumerate(months[offset::step]):
# recalculate original index
index = offset + index*step
# actually repetition of the month is trivial,
# but I put it just to show that the index is right
print(index, element, months[index])
打印:
5 June June
7 August August
9 October October
11 December December
您可以使用 itertools.islice()
+ enumerate()
到 select 个具有原始索引的元素:
>>> import calendar
>>> from itertools import islice
>>> for i, month in islice(enumerate(calendar.month_abbr), 6, None, 2):
... print(i, month)
...
6 Jun
8 Aug
10 Oct
12 Dec
它不复制切片信息并使用具有熟悉行为的现有函数。
或者如果你知道原来的iterable很小;你可以打电话给 list()
:
>>> list(enumerate(calendar.month_abbr))[6::2]
[(6, 'Jun'), (8, 'Aug'), (10, 'Oct'), (12, 'Dec')]