18 октября 2012 г.

Генераторы списков


Генераторы списков, знакомство

Генераторы списков представляют  один из самых заметных инструментов, где используется протокол итераций. Генераторы списков, как это не странно, предназначены для удобной обработки списков, к которой можно отнести и создание новых списков, и модификацию существующих.
Использование генераторов списков  для работы с файлами:
У объекта файла имеется метод readlines, который загружает файл целиком в список строк
>>> f = open(‘script1.py’)
>>> lines = f.readlines()
>>> lines
[‘import sys\n’, ‘print(sys.path)\n’, ‘x = 2\n’, ‘print(2 ** 33)\n’]


Этот  фрагмент работает,  но все  строки в списке  оканчиваются символом новой строки (\n). 


-----------------------------------------------------------------


Далее обработаем каждую строку в списке функцией rstrip, чтобы удалить завершающие пробельные  символы


>>> lines = [line.rstrip() for line in lines]
>>> lines
[‘import sys’, ‘print(sys.path)’, ‘x = 2’, ‘print(2 ** 33)’]
-----------------------------------------------------------------


>>> lines = [line.rstrip() for line in open(‘script1.py’)]
>>> lines
[‘import sys’, ‘print(sys.path)’, ‘x = 2’, ‘print(2 ** 33)’]

Читаем из файла по одной строке за раз – вызовом метода __next__ файла, пропускать строку через функцию rstrip и добавляем результат в список.
-----------------------------------------------------------------

Выполнение строковых операций:

>>> [line.upper() for line in open(‘script1.py’)]
[‘IMPORT SYS\n’, ‘PRINT(SYS.PATH)\n’, ‘X = 2\n’, ‘PRINT(2 ** 33)\n’]

>>> [line.rstrip().upper() for line in open(‘script1.py’)]
[‘IMPORT SYS’, ‘PRINT(SYS.PATH)’, ‘X = 2’, ‘PRINT(2 ** 33)’]

>>> [line.split() for line in open(‘script1.py’)]
[[‘import’,’sys’], [‘print(sys.path)’], [‘x’,’=’,’2’], [‘print(2’,’**’,’33)’]]

>>> [line.replace(‘ ‘, ‘!’) for line in open(‘script1.py’)]
[‘import!sys\n’, ‘print(sys.path)\n’, ‘x!=!2\n’, ‘print(2!**!33)\n’]

>>> [(‘sys’ in line, line[0]) for line in open(‘script1.py’)]
[(True, ‘i’), (True, ‘p’), (False, ‘x’), (False, ‘p’)]
-----------------------------------------------------------------

Расширенный синтаксис генераторов списков:

>>> lines = [line.rstrip() for line in open(‘script1.py’) if line[0] == ‘p’]
>>> lines
[‘print(sys.path)’, ‘print(2 ** 33)’]
Отбираем только строки, начинающиеся с символа p.

>>> res = []
>>> for line in open(‘script1.py’):
...     if line[0] == ‘p’:
...         res.append(line.rstrip())
...
>>> res
[‘print(sys.path)’, ‘print(2 ** 33)’]
Более подробное описание.
-----------------------------------------------------------------

В языке Python имеются различные встроенные функции, позволяющие об- Python имеются различные встроенные функции, позволяющие об-  имеются различные  встроенные функции, позволяющие обрабатывать итерируемые объекты:

sorted - сортирует элементы итерируемого объекта,  
zip -  объединяет  элементы  итерируемых  объектов, 
enumerate - создает пары из элементов итерируемых объектов и их позиций, 
filter отбирает элементы, для которых указанная функция возвращает истинное значение, 
reduce  выполняет указанную операцию, объединяя все элементы в итерируемом объекте. 
Все эти функции принимают итерируемые объекты, при этом в Python 3.0 функции zip, enumerate и filter еще и возвращают итерируемые объекты, подобно функции map.

Далее пример применения этих функций:

>>> sorted(open(‘script1.py’))
[‘import sys\n’, ‘print(2 ** 33)\n’, ‘print(sys.path)\n’, ‘x = 2\n’]
>>> list(zip(open(‘script1.py’), open(‘script1.py’)))
[(‘import sys\n’, ‘import sys\n’), (‘print(sys.path)\n’, ‘print(sys.path)\n’),
(‘x = 2\n’, ‘x = 2\n’), (‘print(2 ** 33)\n’, ‘print(2 ** 33)\n’)]
>>> list(enumerate(open(‘script1.py’)))
[(0, ‘import sys\n’), (1, ‘print(sys.path)\n’), (2, ‘x = 2\n’),
(3, ‘print(2 ** 33)\n’)]
>>> list(filter(bool, open(‘script1.py’)))
[‘import sys\n’, ‘print(sys.path)\n’, ‘x = 2\n’, ‘print(2 ** 33)\n’]
>>> import functools, operator
>>> functools.reduce(operator.add, open(‘script1.py’))
‘import sys\nprint(sys.path)\nx = 2\nprint(2 ** 33)\n’
-----------------------------------------------------------------

Другие функции для работы с итерируемыми объектами:


>>> sum([3, 2, 4, 1, 5, 0])    # sum работает только с числами
15
>>> any([‘spam’, ‘’, ‘ni’])
True
>>> all([‘spam’, ‘’, ‘ni’])
False
>>> max([3, 2, 5, 1, 4])
5
>>> min([3, 2, 5, 1, 4])
1
-----------------------------------------------------------------

Функции max и min могут применяться и к файлам :

>>> max(open(‘script1.py’))    # Поиск строк с максимальным и 
                               минимальным 
‘x = 2\n’                      # строковым значением
>>> min(open(‘script1.py’))
‘import sys\n’
-----------------------------------------------------------------

Функции которые читают файл построчно:

>>> list(open(‘script1.py’))
[‘import sys\n’, ‘print(sys.path)\n’, ‘x = 2\n’, ‘print(2 ** 33)\n’]
>>> tuple(open(‘script1.py’))
(‘import sys\n’, ‘print(sys.path)\n’, ‘x = 2\n’, ‘print(2 ** 33)\n’)
>>> ‘&&’.join(open(‘script1.py’))
‘import sys\n&&print(sys.path)\n&&x = 2\n&&print(2 ** 33)\n’
>>> a, b, c, d = open(‘script1.py’)
>>> a, d
(‘import sys\n’, ‘print(2 ** 33)\n’)
>>> a, *b = open(‘script1.py’)     # Расширенная форма в 3.0
>>> a, b
(‘import sys\n’, [‘print(sys.path)\n’, ‘x = 2\n’, ‘print(2 ** 33)\n’])
-----------------------------------------------------------------

Еще  один, итерационный контекст:

>>> def f(a, b, c, d): print(a, b, c, d, sep=’&’)
...
>>> f(1, 2, 3, 4)
1&2&3&4
>>> f(*[1, 2, 3, 4])       # Распаковывание списка в аргументы
1&2&3&4
>>> f(*open(‘script1.py’)) # Можно даже выполнить обход строк в файле!
import sys
&print(sys.path)
&x = 2
&print(2 ** 33)

2 комментария:

  1. заучено, пригодится ! =)

    ОтветитьУдалить
    Ответы
    1. Подписывайся, будет еще много чего, что пригодится )

      Удалить