2014-11-02 1 views
0

У меня есть предопределенные функции lets(string):Как написать func, чтобы получить первый/второй/третий и т. Д. Из каждого итератора без использования itertools?

def lets(string): 
    for i in range(len(string)): 
     yield string[i] 

И мне нужно, чтобы определить альтернативную функцию, которая принимает число итерируемых:

def alternate(*args): 
    ... 

и использование этой функции в этих двух способах предположит, изготавливал результат как следующее:

' '.join([str(i) for i in alternate('abcde','fg','hijk')]) 
-->a f h b g i c j d k e 

' '.join([str(i) for i in alternate(lets('abcde'),lets('fg'),lets('hijk'))]) 
-->a f h b g i c j d k e 

Я пробовал несколько способов определить альтернативу знаниями Я знаю, что до сих пор, но я никогда не смогу сделать это, вот мой самый близкий вариант:

def alternate(*args): 
    n=0 
    while n in range(11): 
     for i in args: 
      try: 
       yield list(i)[n] 
      except : 
       yield next(iter(i)) 
     n+=1 

Но это дает мне:

' '.join([str(i) for i in alternate('abcde','fg','hijk')]) 
-> a f h b g i c f j d f k e f h a f h a f h a f h a f h a f h a f h 
' '.join([str(i) for i in alternate(lets('abcde'),lets('fg'),lets('hijk'))]) 
-> a f h 

Может кто-то пожалуйста, помогите мне с этим, я новичок использовать генератор python, действительно оценили!

+0

код [itertools рецепт раздел] (https://docs.python.org/2/library/itertools.html#recipes) имеет 'roundrobin()' функция, которая делает именно это. –

+1

Кроме того, это не проблема, о которой вы просили, но вы можете перебирать строки с циклом for, например 'for s в строке:' get 's', который является символом в определенной точке – muthan

ответ

0

Внешний цикл while должен проходить через количество раз, когда максимальная длина элемента args.

Тогда для каждого элемента args вы можете дать только в том случае, если есть значение. Проверка того, есть ли значение или нет, удаляется с помощью части, отличной от try; однако его также можно контролировать с помощью основного оператора if-else.

def alternate(*args): 
    n=0 
    while n in range(max(map(len, args))): 
     for i in args: 
      try: 
       yield list(i)[n] 
      except : 
       pass 
     n+=1 
+0

Большое спасибо! Это очень помогает, но работает только на альтернативных ('abcde', 'fg', 'hijk'). alternate (let ('abcde'), let ('fg'), let ('hijk')) даст объект TypeError: объект типа 'generator' не имеет len(). Есть ли способ сделать это без использования len()? – Saoish

+0

Если это полезно, вы можете пометить мой ответ как правильное решение :) –

0

Ваша задача заключается в следующем:

yield list(i)[n] 

, когда я это генератор, а не список, первый раз, когда вы звоните list(i) вы будете потреблять генератор. Вы должны вместо преобразования в список, просто дать следующее значение:

yield next(i) 
+0

Если я изменю его, чтобы получить следующий (i), он немедленно вызовет StopIteration. – Saoish

+0

@Saoish - заверните оператор в try/except и игнорируйте исключение. –

+0

Можете ли вы показать мне фактические коды? Я пробовал то, что вы сказали, но получается масса. – Saoish

Смежные вопросы