2014-01-29 3 views
1

고정 된 수의 사용자를 목록에서 반환하는 생성기를 만들고 싶습니다. 원하는 사용자 수가 목록의 길이보다 큰 경우 마지막 사용자가 반복됩니다. 나는이 아래 수행하는 발전기를 썼다 :이 생성기를 정의하는 더 좋은 방법이 있습니까?

def gen_users(users, total): 
    num_users = len(users) 
    cur_user = 0 
    while cur_user < total: 
     if cur_user >= num_users: 
      yield users[-1] 
     else: 
      yield users[cur_user] 
     cur_user += 1 

을 나는 사용자 users = ['one', 'two', 'three']의 목록을했고, 내가 다시 one, two, three, three, three을 얻을 gen_users(users, 5)를 호출 그래서 경우.

더 많은 pythonic 방법이 있나요? 발전기를이 문제에 대한 유효한 접근 방법으로 사용하고 있습니까? itertools.islice를 사용

답변

2

:

>>> import itertools 
>>> 
>>> def gen_users(users, total): 
...  # assert users and total > 0 
...  for i, user in enumerate(itertools.islice(users, total)): 
...   yield user 
...  for _ in range(total - i - 1): # i -> last index 
...   yield user 
... 
>>> list(gen_users([1,2,3], 5)) 
[1, 2, 3, 3, 3] 
>>> list(gen_users([1,2,3], 2)) 
[1, 2] 

은 또는 당신 users[:total]을 사용할 수 있지만 임시 시퀀스를 생성합니다.

UPDATE 한스 Zauber의 코드를 약간 수정 된 버전

:

>>> from itertools import islice, chain, repeat 
>>> 
>>> def gen_users(users, total): 
...  return islice(chain(users, repeat(users[-1])), total) 
... 
>>> list(gen_users([1,2,3], 5)) 
[1, 2, 3, 3, 3] 
>>> list(gen_users([1,2,3], 3)) 
[1, 2, 3] 
>>> list(gen_users([1,2,3], 2)) 
[1, 2] 
+0

, 나는 거기에 알고 있던이 될 수있는 이렇게하는 더 좋은 방법! 감사. –

+0

'total'이 큰 경우'xrange'를 사용하면 개선 될 수 있습니다. – Bach

+0

@ HansZauber,이 코드가 Python 2.x, 3.x에서 실행되도록'range'를 사용했습니다. – falsetru

2

이 한 줄 시도 : 내가 원하는 정확히 무엇을

import itertools 
gen_users = lambda users, total: itertools.chain(itertools.islice(users, total), itertools.repeat(users[-1], total-len(users))) 
+0

'list (gen_users ([1,2,3], 2))'를 시도하십시오. – falsetru

+0

수정 됨,이 경우를 잊어 버렸습니다. – Bach

+0

이 답변은 정말 대단합니다. 감사. –

관련 문제