Выводить n элементов списка при каждом запуске функции

#python #list #for-loop

#python #Список #для цикла

Вопрос:

У меня есть список строк, и мне нужно создать функцию, которая выводит n элементов списка при каждом запуске. Например:

 book1 = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o']
 

Ожидаемый результат при первом запуске функции, если n = 5 :

 a
b
c
d
e
 

второй раз:

 f
g
h
i
j
 

Я пробовал это:

 def print_book(book):
    printed = book
    while printed != []:
        for i in range(0, len(book), 5):
            new_list = (book[i:i 5])
            for el in new_list:
                print(el)
        break
    del(printed[i:i 10])
 

И я либо распечатываю весь список, либо в конечном итоге печатаю первые n элементов при каждом запуске функции.
Если этот вопрос уже задавался, пожалуйста, укажите на него мне, я бы действительно оценил его. Спасибо!

Комментарии:

1. Вы хотите исчерпать итератор один раз или хотите выполнить итерацию по списку несколько раз?

2. @theProgrammer Я думаю, что в любом случае это сработает, если я распечатаю только n последовательных элементов (а не одни и те же 5 элементов каждый раз, а не весь список)

3. @VarvaraLitvinova вы хотите сохранить элементы в своем списке. или это нормально — удалять элементы по мере выполнения итерации?

4. Если вы хотите сделать это чистым способом, вам нужно создать какую-то структуру данных с состоянием, иначе говоря, объект. Закрытие тоже сработало бы. В этом случае у вас будет функция, которая будет принимать ваш список в качестве входных данных и возвращать функцию, которая доставляет часть списка каждый раз, когда вы ее вызываете.

5. Как говорит nilo, вы должны полагаться на сохранение состояния между вызовами функций. Вы либо делаете это, изменяя глобальную переменную (влияя на глобальное состояние), что очень просто, но не рекомендуется в практике программирования, либо сохраняете состояние локально в своей функции или объекте. Это можно сделать (по крайней мере) с помощью пользовательского класса, или замыкания, или итератора, или используя изменяемые аргументы по умолчанию. Я поддерживаю этот вопрос, потому что он может вызвать так много разнообразных ответов с помощью разных методов, что делает его интересным.

Ответ №1:

Распространенным подходом является выражение генератора. Выражение генератора выдает его значение, когда это необходимо, и, следовательно, весь список не будет создан сразу

Решением вашей проблемы может быть следующее

 book1 = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o']

def yield_book(book1):
    for i in book1:
        yield i;
                
def print_n_item(gen, n):
    count = 0
    for i in gen:
        if count == n:
            return
        print(i)
        count  = 1
        
gen = yield_book(book1)
print_n_item(gen, 5) # prints a,  b,  c, d, e
print_n_item(gen, 5) # prints f,  g,  h,  i,  j
print_n_item(gen, 5) # prints k,  l,  m,  n,  o

 

Этот подход исчерпывает итератор и, следовательно, может быть использован один раз, чтобы повторить итерацию снова, вам нужно вызвать yield_book , чтобы вернуть новый generator

Ответ №2:

Я думаю, вы можете попробовать следующую пользовательскую функцию, которая применялась к итератору book

 def print_book(book):
    cnt = 0
    while cnt < 5:
        try:
            print(next(book))
        except StopIteration:
            print("You have reached the end!")
            break
        cnt  = 1
 

такое, что

 >>> bk1 = iter(book1)
>>> print_book(bk1)
a
b
c
d
e
>>> print_book(bk1)
f
g
h
i
j
>>> print_book(bk1)
k
l
m
n
o
>>> print_book(bk1)
You have reached the end!
 

Ответ №3:

Как упоминалось в комментарии, вы действительно хотите инкапсулировать состояние в какую-то структуру данных. Классовый подход:

 class Printer:
    def __init__(self, book, n=5):
        self.book = book
        self.index = 0
        self.n = n

    def print(self):
        index = self.index
        self.index  = self.n
        for t in self.book[index:self.index]:
            print(t)


book1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o']
printer = Printer(book1)
printer.print()
print()
printer.print()
 

Результат:

 a
b
c
d
e

f
g
h
i
j
 

Комментарии:

1. По сравнению с решением @ThomasIsCoding, в этом вы в основном реализуете свой собственный итератор. Хотя, как правило, не следует изобретать велосипед, это хороший способ обучения.

Ответ №4:

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

 book1 = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o']
    
def print_books(n, i=[0]):
    list(map(print, book1[i[0]:i[0]   n]))
    i[0] = (i[0]   n) if i[0] < len(book1) else 0

print_books(5)
print()
print_books(5)
 

n это количество элементов списка для печати, которое сбрасывается на 0 при достижении конца списка; i это список, используемый для хранения индекса первого элемента, который еще не напечатан.

Вам следует избегать этой функции, потому что она может генерировать странное и неожиданное поведение (посмотрите здесь ), но ее можно использовать для сохранения состояния функции, и я подумал, что это заслуживает упоминания здесь.

Ответ №5:

И как фабрика функций

 book_1 = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o']

def printer_factory(book, n = 5):
    i = 0
    def printer():
        nonlocal i
        stop = min(i n, len(book))
        while i < stop:
            print(book[i])
            i  = 1
    return printer

printer_1 = printer_factory(book_1)

printer_1()
printer_1()
 

Ответ №6:

Я согласен с nilo. Ниже приведено решение, основанное на его ответе. В этом решении вы вернетесь к началу списка, как только пройдете весь список.

 book1 = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o']

class Printer:
    def __init__(self, book):
        self.index = 0
        self.book = book

    def print(self, n):

        for i in range(0, n):
            print(self.book[self.index % len(self.book)])
            self.index  = 1


book = Printer(book1)
book.print(5)
print("")
book.print(5)
print("")
book.print(7)

 

Вывод:

 a
b
c
d
e

f
g
h
i
j

k
l
m
n
o
a
b


 

Ответ №7:

Я не внес много изменений в вашу программу.Так что это может быть немного полезно для вашего понимания.

 book1= ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o']
def print_book(book,a,n):
    printed = book
    if printed != []:
    
        new_list=[]#i have created a list
        for i in range(a,n 1):
            new_list.append(book[i])#append is used to add elements to list
        
        for el in new_list:
                print(el)
    
print_book(book1,0,4)#prints a,b,c,d,e
print_book(book1,5,9)#prints f,g,h,i,j