2014-10-06 1 views
3

мне нужно подражать izip_longest из itertools в Python 2,4Что я мог бы использовать вместо следующего() в Python 2.4

import itertools 
class Tools: 
    @staticmethod 
    def izip_longest(*args, **kwds): 
     # izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D- 
     fillvalue = kwds.get('fillvalue') 
     counter = [len(args) - 1] 
     def sentinel(): 
      if not counter[0]: 
       raise ZipExhausted 
      counter[0] -= 1 
      yield fillvalue 
     fillers = itertools.repeat(fillvalue) 
     iterators = [itertools.chain(it, sentinel(), fillers) for it in args] 
     try: 
     while iterators: 
      yield tuple(map(next, iterators)) 
     except ZipExhausted: 
      pass  


class ZipExhausted(Exception): 
    pass 

Все работает отлично, пока я не достигну yield tuple(map(next, iterators)); Python 2.4 бросает ошибку

NameError: global name 'next' is not defined 

и завершает работу.

Что я могу использовать вместо next, чтобы сделать izip_longest работать в Python 2.4?

Или есть ли другая функция в Python 2.4, которая возвращает тот же результат, что и izip_longest()?

+0

Из любопытства, почему вы используете класс с статический метод? Почему бы просто не сделать эту функцию? –

+0

Немного связанный (не совсем дубликат): http://stackoverflow.com/q/25810855/1639625 –

ответ

6

В Python 2.6 добавлен next() function. Используйте метод next из итераторов вместо:

while iterators: 
    yield tuple([it.next() for it in iterators]) 

или определить свою собственную next() функцию; вы не используете default аргумент, поэтому для более простого случая, что бы:

def next(it): 
    return it.next() 

но полная версия будет:

_sentinel = object() 

def next(it, default=_sentinel): 
    try: 
     return it.next() 
    except StopIteration: 
     if default is _sentinel: 
      raise 
     return default 
+0

Спасибо. Теперь он отлично работает :) – BigZ